public static TimedMove CreateUndoMove(int wait_before, int wait_after) { TimedMove timed_move = new TimedMove(new Move(0, 1), wait_before, wait_after); timed_move.undo = true; return timed_move; }
public GameStateMoveAction(GameState gs, GameState original, long time, TimedMove move, List<TimedMove> madeMoves) : base(gs, time) { this.original = original; this.move = move; this.madeMoves = madeMoves; }
public TimedMove(TimedMove move) : base(move) { this.wait_before = move.wait_before; this.wait_after = move.wait_after; this.undo = move.undo; }
public GameStateMoveAction(GameState gs, GameState original, long time, TimedMove move, List <TimedMove> madeMoves) : base(gs, time) { this.original = original; this.move = move; this.madeMoves = madeMoves; }
public static GameStateAction Deserialize(string s) { string[] t = s.Split('|'); GameState original = GameState.Deserialize(t[0]); GameState gs = GameState.Deserialize(t[1]); long time = long.Parse(t[2]); /*Stack<Move> madeMoves = new Stack<Move>(); * foreach (string d in t[2].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Reverse()) * { * Move m = new Move(d); * madeMoves.Push(m); * }*/ List <TimedMove> madeMoves = new List <TimedMove>(); foreach (string d in t[3].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)) { TimedMove m = TimedMove.Deserialize(d); madeMoves.Add(m); } TimedMove move = null; if (t[4] != "X") { move = TimedMove.Deserialize(t[4]); } return(new GameStateMoveAction(gs, original, time, move, madeMoves)); }
public TimedMove(TimedMove move) : base(move) { this.wait_before = move.wait_before; this.wait_after = move.wait_after; this.undo = move.undo; }
public static TimedMove CreateUndoMove(int wait_before, int wait_after) { TimedMove timed_move = new TimedMove(new Move(0, 1), wait_before, wait_after); timed_move.undo = true; return(timed_move); }
public override TimedPlay TimedPlayOnRoll(GameState gamestate, List <PlayHint> hints, VenueUndoMethod undo_method) { List <Play> legal_plays = gamestate.Board.LegalPlays(gamestate.PlayerOnRoll, gamestate.Dice); List <Move> forced_moves = Board.ForcedMoves(legal_plays); // Sort the moves. foreach (PlayHint hint in hints) { SortMoves(gamestate, hint.Play, legal_plays, forced_moves); } double optimal_move_equity = hints[0].Equity; double doubtful = 0.04; double bad = 0.08; double very_bad = 0.16; /*List<PlayHint> good_hints = new List<PlayHint>(); * List<PlayHint> doubtful_hints = new List<PlayHint>(); * List<PlayHint> bad_hints = new List<PlayHint>(); * List<PlayHint> very_bad_hints = new List<PlayHint>(); * * // Skip the first one as it is the optimal one. * for (int i = 1; i < hints.Count; i++) * { * double diff = optimal_move_equity - hints[i].Equity; * if (diff >= very_bad) * very_bad_hints.Add(hints[i]); * else if (diff >= bad) * very_bad_hints.Add(hints[i]); * else if (diff >= doubtful) * doubtful_hints.Add(hints[i]); * else * good_hints.Add(hints[i]); * }*/ /*if (legal_plays.Count != hints.Count) * { * Console.WriteLine("Legal plays and hint plays mis-match"); * Console.WriteLine("Legal plays: "); * foreach (Play play in legal_plays) * Console.WriteLine(play); * Console.WriteLine("Hint plays: "); * foreach (PlayHint hint in hints) * Console.WriteLine(hint); * * throw new Exception(); * }*/ // Is the play an obvious move? Check the equity difference to second best move. bool obvious_move = false; if (legal_plays.Count == 1 || (hints.Count > 1 && (hints[1].Equity - optimal_move_equity) > bad)) { obvious_move = true; } List <Play> fake_plays = new List <Play>(); if (!obvious_move && undo_method != VenueUndoMethod.None) { // Choose the amount of fake plays. int fake_plays_to_choose = 0; if (random.NextDouble() <= undo_probability) { fake_plays_to_choose++; while (random.NextDouble() < 0.1) { fake_plays_to_choose++; } } // Choose the fake plays. for (int i = 0; i < fake_plays_to_choose; i++) { int fake_play_index = 1; while (random.Next(3) == 0) { fake_play_index++; if (fake_play_index >= hints.Count) { fake_play_index = 0; } } // Make it partial? if (random.NextDouble() <= 0.3) { Play partial_play = new Play(); int moves_to_choose = 1; while (random.Next(4) == 0) { moves_to_choose++; if (moves_to_choose >= hints[fake_play_index].Play.Count) { moves_to_choose = 1; } } for (int m = 0; m < moves_to_choose; m++) { partial_play.Add(hints[fake_play_index].Play[m]); } fake_plays.Add(partial_play); } else { fake_plays.Add(hints[fake_play_index].Play); } } } TimedPlay timed_play = new TimedPlay(); // Add undo sequences using fake plays. if (!obvious_move && hints.Count > 1 && fake_plays.Count > 0) { List <Move> made_moves = new List <Move>(); //Queue<Move> made_moves = new Queue<Move>(); //Stack<Move> made_moves = new Stack<Move>(); foreach (Play fake_play in fake_plays) { for (int i = 0; i < fake_play.Count; i++) { /*if (made_moves.Count > 0) * { * int shared = 0; * while (shared < made_moves.Count && shared < fake_play.Count && made_moves[shared] == fake_play[shared]) * shared++; * } * else*/ timed_play.Add(new TimedMove(fake_play[i], 0, 0)); //made_moves.Push(fake_play[i]); } // Undo all if (undo_method == VenueUndoMethod.UndoLast) { for (int i = 0; i < fake_play.Count; i++) { timed_play.Add(TimedMove.CreateUndoMove(0, 0)); } } else { timed_play.Add(TimedMove.CreateUndoMove(0, 0)); } } int m = 0; // TODO: Some how check if current move and previous share some similar so not necessary undo all. foreach (Move move in hints[0].Play) { timed_play.Add(new TimedMove(move, 0, 0)); } } else { // No fake plays, add the optimal move. foreach (Move move in hints[0].Play) { timed_play.Add(new TimedMove(move, 0, 0)); } } int last_from = -2; bool was_last_undo = false; foreach (TimedMove timed_move in timed_play) { if (timed_move.IsUndo) { if (was_last_undo) { timed_move.WaitBefore = Gaussian.Next(500, 200, 10000, 600, 1.5); timed_move.WaitAfter = random.Next(200); } else { timed_move.WaitBefore = Gaussian.Next(1000, 500, 10000, 2000, 1.5); timed_move.WaitAfter = Gaussian.Next(1000, 50, 10000, 2000, 1.5); } last_from = -2; was_last_undo = true; continue; } was_last_undo = false; if (timed_move.From != last_from) { //timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 500, 3.0); //timed_move.WaitAfter = random.Next(300); timed_move.WaitBefore = Gaussian.Next(1000, 250, 2000, 1000, 3.0); timed_move.WaitAfter = random.Next(300); } else { //timed_move.WaitBefore = Gaussian.Next(250, 100, 2000, 200, 3.0); //timed_move.WaitAfter = random.Next(100); timed_move.WaitBefore = Gaussian.Next(500, 250, 2000, 200, 3.0); timed_move.WaitAfter = random.Next(250); } // Speedup for pure race or when we have a blockade. if (random.NextDouble() <= 0.9 && (gamestate.Board.IsPureRace() || HasBlockaded(gamestate) || obvious_move)) { timed_move.WaitBefore = (int)(timed_move.WaitBefore * (0.4 + 0.3 * random.NextDouble())); timed_move.WaitAfter = (int)(timed_move.WaitAfter * (0.4 + 0.3 * random.NextDouble())); } last_from = timed_move.From; } // Normalize with coefficient. foreach (TimedMove timed_move in timed_play) { timed_move.WaitBefore = (int)(timed_move.WaitBefore * coefficient); timed_move.WaitAfter = (int)(timed_move.WaitAfter * coefficient); } return(timed_play); }
void Form1_MouseClick(object sender, MouseEventArgs e) { if (currentGameState.PlayerOnTurn == 0 && !currentGameState.HasOffer && currentGameState.DiceRolled && legalPlays.Count > 0 && madeMoves.Count < legalPlays[0].Count) { BoundingChequer chequer = ClickTest(e.Location); if (chequer == null) return; int[] dice = currentGameState.Dice; int from = chequer.Slot; if (dice[0] != dice[1]) { int die = -1; if (unusedDice.Count == 2) { if (e.Button == MouseButtons.Left) die = Math.Max(unusedDice[0], unusedDice[1]); else if (e.Button == MouseButtons.Right) die = Math.Min(unusedDice[0], unusedDice[1]); else return; } else die = unusedDice[0]; int to = chequer.Slot - die; if (to < -1) to = -1; Move move = new Move(from, to); if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die)) { if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1) move.AddHitPoint(to); watch.Stop(); /*Stack<Move> s = new Stack<Move>(); foreach (Move m in madeMoves.Reverse()) s.Push(m.Clone());*/ List<TimedMove> h = new List<TimedMove>(); foreach (TimedMove m in moveHistory) h.Add(new TimedMove(m)); TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0); moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h)); currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move); madeMoves.Push(move); moveHistory.Add(tmove); unusedDice.Remove(die); usedDice.Push(die); UpdateControls(); } else { if (unusedDice.Count == 2) { die = (dice[0] == die) ? dice[1] : dice[0]; to = chequer.Slot - die; if (to < -1) to = -1; move = new Move(from, to); if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die)) { if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1) move.AddHitPoint(to); watch.Stop(); /*Stack<Move> s = new Stack<Move>(); foreach (Move m in madeMoves.Reverse()) s.Push(m.Clone());*/ //moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s)); List<TimedMove> h = new List<TimedMove>(); foreach (TimedMove m in moveHistory) h.Add(new TimedMove(m)); TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0); moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h)); currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move); madeMoves.Push(move); moveHistory.Add(tmove); unusedDice.Remove(die); usedDice.Push(die); UpdateControls(); } } //else //Console.WriteLine("Illegal move " + from + "/" + to); } } else { int to = chequer.Slot - dice[0]; if (to < -1) to = -1; Move move = new Move(from, to); if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, dice[0])) { if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1) move.AddHitPoint(to); watch.Stop(); /*Stack<Move> s = new Stack<Move>(); foreach (Move m in madeMoves.Reverse()) s.Push(m.Clone()); moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s));*/ List<TimedMove> h = new List<TimedMove>(); foreach (TimedMove m in moveHistory) h.Add(new TimedMove(m)); TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0); moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h)); currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move); madeMoves.Push(move); moveHistory.Add(tmove); unusedDice.Remove(dice[0]); usedDice.Push(dice[0]); UpdateControls(); } } // Fix problem when making an illegal move the watch resets itsefl } }
public void Add(TimedMove timed_move) { timed_moves.Add(timed_move); }
public static GameStateAction Deserialize(string s) { string[] t = s.Split('|'); GameState original = GameState.Deserialize(t[0]); GameState gs = GameState.Deserialize(t[1]); long time = long.Parse(t[2]); /*Stack<Move> madeMoves = new Stack<Move>(); foreach (string d in t[2].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Reverse()) { Move m = new Move(d); madeMoves.Push(m); }*/ List<TimedMove> madeMoves = new List<TimedMove>(); foreach (string d in t[3].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)) { TimedMove m = TimedMove.Deserialize(d); madeMoves.Add(m); } TimedMove move = null; if (t[4] != "X") move = TimedMove.Deserialize(t[4]); return new GameStateMoveAction(gs, original, time, move, madeMoves); }
public void Add(TimedMove timed_move) { timed_moves.Add(timed_move); }