public MoveModel newMove(MoveStats stats, bool right) { //foreach (MoveModel moveModel in moves) if (moveModel.Stats.Equals(stats)) return null; MoveModel move = new MoveModel(stats, right, playerIndex); moves.Add(move); return move; }
public MoveModel newMove(MoveStats stats, bool right) { //foreach (MoveModel moveModel in moves) if (moveModel.Stats.Equals(stats)) return null; MoveModel move = new MoveModel(stats, right, playerIndex); moves.Add(move); return(move); }
/// <summary> /// Returns the move found to have highest win-rate after performing, in parallel, the specified number of Monte-Carlo simulations on the input game. /// </summary> /// <param name="game">The current game.</param> /// <param name="simulations">The number of simulations to perform.</param> public static TMove ParallelSearch(TGame game, int simulations) { TPlayer aiPlayer = game.CurrentPlayer; List <TMove> legalMoves = game.GetLegalMoves(); int count = legalMoves.Count; MoveStats[] moveStats = new MoveStats[count]; ParallelNET35.Parallel.For(0, simulations, () => { return(ThreadLocalRandom.NewRandom()); }, (i, loop, localRandom) => { int moveIndex = localRandom.Next(0, count); TGame copy = game.DeepCopy(); copy.DoMove(legalMoves[moveIndex]); while (!copy.IsGameOver()) { copy.DoMove( copy.GetLegalMoves().RandomItem(localRandom)); } Interlocked.Add(ref moveStats[moveIndex].executions, 1); if (copy.IsWinner(aiPlayer)) { Interlocked.Add(ref moveStats[moveIndex].victories, 1); } return(localRandom); }, (x) => { } ); int bestMoveFound = 0; double bestScoreFound = 0f; for (int i = 0; i < count; i++) { double score = moveStats[i].Score(); if (score > bestScoreFound) { bestScoreFound = score; bestMoveFound = i; } } //for (int i = 0; i < legalMoves.Count; i++) // Console.WriteLine("Move " + legalMoves[i] + " has " + moveStats[i].victories + " victories / " + moveStats[i].executions + " executions."); return(legalMoves[bestMoveFound]); }
public MoveModel(MoveStats stats, bool right, int playerIndex) { Stats = stats; attackTimeLeft = stats.Duration; chargeTime = 0; Started = false; Ended = false; Xdirection = right ? new Vector2(1, 1) : new Vector2(-1, 1); PlayerIndexes = new List<int>(); PlayerIndexes.Add(playerIndex); }
public void StateChanged(CharacterState oldState, CharacterState newState, MoveStats move) { switch (newState) { case CharacterState.none: if (oldState == CharacterState.running) AddAnimation(0, 2, true); else if (oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_noneStart, stats.ani_noneEnd, true); } else StartAnimation(stats.ani_noneStart, stats.ani_noneEnd, true); break; case CharacterState.running: if(oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_runStart, stats.ani_runEnd, true); } else StartAnimation(stats.ani_runStart, stats.ani_runEnd, true); break; case CharacterState.braking: if(oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_brake, stats.ani_brake, true); } else StartAnimation(stats.ani_brake, stats.ani_brake, true); break; case CharacterState.jumping: StartAnimation(stats.ani_jumpStart, stats.ani_jumpEnd, false); AddAnimation(stats.ani_fallStart, stats.ani_fallEnd, true); break; case CharacterState.falling: StartAnimation(stats.ani_fallStart, stats.ani_fallEnd, true); break; case CharacterState.takingHit: StartAnimation(stats.ani_takeHitStart, stats.ani_takeHitEnd, true); break; case CharacterState.attacking: StartAnimation(move.AniFrom, move.AniTo, false, move.Duration); break; case CharacterState.shielding: break; case CharacterState.charging: StartAnimation(move.AniStartChargeFrom, move.AniStartChargeTo, false, move.MinWait); AddAnimation(move.AniChargeLoopFrom, move.AniChargeLoopTo, true); break; default: break; } if (newState != CharacterState.running) fps = Constants.FPS; }
//add new move to GameTree internal MoveStats RegisterGameResult(BoardMove mv, bool win) // GameBoard brd, GameMove mv, bool win) { Tuple <GameMove, MoveStats> res = Tuple.Create(null as GameMove, null as MoveStats); if (tree.ContainsKey(mv.Board)) { //do we have this move registered for this board? var brdMoves = tree[mv.Board]; if (brdMoves.ContainsKey(mv.Move.Position)) { res = brdMoves[mv.Move.Position]; //register win res.Item2.RegisterResult(win); //store modified stats into moves dictionary brdMoves[mv.Move.Position] = res; //store modified move dictionary into boards disctionary tree[mv.Board] = brdMoves; } else { //no make new entry for this board and register win res = Tuple.Create(mv.Move, new MoveStats()); res.Item2.RegisterResult(win); //add stats to moves dictionary brdMoves.Add(mv.Move.Position, res); //add gamemove to board dictionary tree[mv.Board] = brdMoves; } //res.Parent = this; } else { //board not found create new board //create new move stat var mvStat = new MoveStats(); mvStat.RegisterResult(win); //create board entry //add to board dictionary var entry = new Dictionary <int, Tuple <GameMove, MoveStats> >() { { mv.Move.Position, Tuple.Create(mv.Move, mvStat) } }; tree.Add(mv.Board, entry); } return(res.Item2); }
private void Start() { body = GetComponent <Rigidbody>(); switch (defaultMovePlane) { case MovementPlane.XY: rotationAxis = Vector3.forward; break; case MovementPlane.XZ: rotationAxis = Vector3.up; break; } stats = defaultStats; }
/// <summary> /// Returns the move found to have highest win-rate after performing the specified number of Monte-Carlo simulations on the input game. /// </summary> /// <param name="game">The current game.</param> /// <param name="simulations">The number of simulations to perform.</param> public static TMove Search(TGame game, int simulations) { // hoist all declarations out of the main loop for performance TPlayer aiPlayer = game.CurrentPlayer; List <TMove> legalMoves = game.GetLegalMoves(); int count = legalMoves.Count; MoveStats[] moveStats = new MoveStats[count]; int moveIndex; TGame copy; Random rng = new Random(); for (int i = 0; i < simulations; i++) { moveIndex = rng.Next(0, count); copy = game.DeepCopy(); copy.DoMove(legalMoves[moveIndex]); while (!copy.IsGameOver()) { copy.DoMove( copy.GetLegalMoves().RandomItem(rng)); } moveStats[moveIndex].executions++; if (copy.IsWinner(aiPlayer)) { moveStats[moveIndex].victories++; } } int bestMoveFound = 0; double bestScoreFound = 0f; for (int i = 0; i < count; i++) { double score = moveStats[i].Score(); if (score > bestScoreFound) { bestScoreFound = score; bestMoveFound = i; } } return(legalMoves[bestMoveFound]); }
private void ApplyMove(MoveStats stats, float deltaTime) { float currentXVelocity = Rigidbody.velocity.x; float targetXVelocity = deltaXQueue * stats.MaxVelocity; float newVelocity = currentXVelocity; if (currentXVelocity < targetXVelocity) { newVelocity = Mathf.Min(currentXVelocity + stats.Acceleration * deltaTime, targetXVelocity); } else if (currentXVelocity > targetXVelocity) { newVelocity = Mathf.Max(currentXVelocity - stats.Acceleration * deltaTime, targetXVelocity); } Rigidbody.velocity = new Vector2(newVelocity, Rigidbody.velocity.y); deltaXQueue = 0; }
void IJobChunk.Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { NativeArray <MoveStats> _moveStatsArray = chunk.GetNativeArray(_moveStatsHandle); NativeArray <Translation> _translationArray = chunk.GetNativeArray(_translationHandle); for (int i = 0; i < chunk.ChunkEntityCount; i++) { if (_moveStatsArray[i]._canMove == 1) { _moveStatsArray[i] = new MoveStats { _canMove = _moveStatsArray[i]._canMove, _newPosition = _translationArray[i].Value + (_direction * _dt * _moveStatsArray[i]._moveSpeed), _moveSpeed = _moveStatsArray[i]._moveSpeed }; } } }
private void Start() { body = GetComponent <Rigidbody>(); anim = GetComponent <PlayerAnimator>(); stats = defaultStats; switch (plane) { case MovementPlane.XY: horizontalAxis = Vector3.right; verticalAxis = Vector3.up; break; case MovementPlane.XZ: horizontalAxis = Vector3.right; verticalAxis = Vector3.forward; break; } rotationAxis = Vector3.Cross(horizontalAxis, verticalAxis); }
public void ResetMoveStats() { stats = defaultStats; }
public void SetMoveStats(MoveStats newStats) { stats = newStats; }
public void StateChanged(CharacterState oldState, CharacterState newState, MoveStats move) { switch (newState) { case CharacterState.none: if (oldState == CharacterState.running) { AddAnimation(0, 2, true); } else if (oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_noneStart, stats.ani_noneEnd, true); } else { StartAnimation(stats.ani_noneStart, stats.ani_noneEnd, true); } break; case CharacterState.running: if (oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_runStart, stats.ani_runEnd, true); } else { StartAnimation(stats.ani_runStart, stats.ani_runEnd, true); } break; case CharacterState.braking: if (oldState == CharacterState.falling || oldState == CharacterState.jumping) { StartAnimation(stats.ani_landStart, stats.ani_landEnd, false); AddAnimation(stats.ani_brake, stats.ani_brake, true); } else { StartAnimation(stats.ani_brake, stats.ani_brake, true); } break; case CharacterState.jumping: StartAnimation(stats.ani_jumpStart, stats.ani_jumpEnd, false); AddAnimation(stats.ani_fallStart, stats.ani_fallEnd, true); break; case CharacterState.falling: StartAnimation(stats.ani_fallStart, stats.ani_fallEnd, true); break; case CharacterState.takingHit: StartAnimation(stats.ani_takeHitStart, stats.ani_takeHitEnd, true); break; case CharacterState.attacking: StartAnimation(move.AniFrom, move.AniTo, false, move.Duration); break; case CharacterState.shielding: break; case CharacterState.charging: StartAnimation(move.AniStartChargeFrom, move.AniStartChargeTo, false, move.MinWait); AddAnimation(move.AniChargeLoopFrom, move.AniChargeLoopTo, true); break; default: break; } if (newState != CharacterState.running) { fps = Constants.FPS; } }
private bool Collision(Fixture chara, Fixture obj, Contact list) { bool returnValue = false; if (model.state == CharacterState.attacking && (obj.CollisionCategories != Category.Cat20 || !((MoveModel)obj.Body.UserData).PlayerIndexes.Contains(model.playerIndex)) && currentMove.Stats.Type == MoveType.Body && (currentMove.Stats.StopAtHit || obj.CollisionCategories != Category.Cat11) && currentMove.attackTimeLeft <= currentMove.Stats.Duration - currentMove.Stats.BodyStart) { moves.EndMove(currentMove); moves.RemoveMove(currentMove); view.Rotation = 0; view.BoundBox.Rotation = 0; model.attackMode = false; if ((obj.CollisionCategories == Category.Cat9 || obj.CollisionCategories == Category.Cat10) && chara.Body.Position.Y + view.size.Y / 2 <= obj.Body.Position.Y - (float)obj.Body.UserData / 2) { model.inAir = false; if (obj.CollisionCategories == Category.Cat10) { model.onSoftBox = true; } model.jumpsLeft = 3; } NaturalState(); returnValue = true; } else if ((obj.CollisionCategories == Category.Cat9 || obj.CollisionCategories == Category.Cat10) && (chara.Body.Position.Y + view.size.Y / 2 <= obj.Body.Position.Y - (float)obj.Body.UserData / 2 && view.VelocityY >= -0.001)) { model.inAir = false; if (obj.CollisionCategories == Category.Cat10) { model.onSoftBox = true; } NaturalState(); model.jumpsLeft = 3; returnValue = true; } else if (obj.CollisionCategories == Category.Cat9) { returnValue = true; } else if (obj.CollisionCategories == Category.Cat20) { MoveModel move = (MoveModel)obj.Body.UserData; if (!move.PlayerIndexes.Contains(model.playerIndex) && !model.invounerable) { move.PlayerIndexes.Add(model.playerIndex); MoveStats stats = move.Stats; float ratio = 0; if (stats.Type == MoveType.Charge && move.chargeTime < stats.MaxWait) { ratio = move.chargeTime / stats.MaxWait; } else { ratio = 1; } Vector2 power = ratio * stats.Power; int damage = (int)ratio * stats.Damage; view.Velocity = move.Xdirection * power * (1 + model.damagePoints / 100) * (100 / model.weight); if (Math.Abs(view.VelocityY) == 0) { view.VelocityY = -1; } model.damagePoints += damage; model.setState(CharacterState.takingHit); if (OnHit != null) { OnHit.Invoke(ConvertUnits.ToDisplayUnits(obj.Body.Position), damage, model.damagePoints, move.PlayerIndexes.First(), model.playerIndex, stats.hitSound); } //if (move.Adjustable && ((AdjustableMove)move).StopAtHit) move.attackTimeLeft = 0; } } else if (obj.CollisionCategories == Category.Cat7 || obj.CollisionCategories == Category.Cat8) { OnCharacterDeath.Invoke(this, obj.CollisionCategories == Category.Cat7); } return(returnValue); }
public void setState(CharacterState newState, MoveStats move = null) { if (newState == CharacterState.attacking || newState == CharacterState.charging || newState == CharacterState.shielding) { if(newState != CharacterState.shielding && move == null) throw new NotImplementedException(); attackMode = true; } else attackMode = false; if(newState == CharacterState.jumping || newState == CharacterState.falling) inAir = true; if (newState != state) { view.StateChanged(state, newState, move); state = newState; } }