public void Update(double value, UTTTMove bestMove, UTTTState currentState, Dictionary <int, StateRecord> statesSeen, int iteration)
 {
     this.value     = value;
     this.bestMove  = bestMove;
     this.iteration = iteration;
     statesSeen.Add(currentState.GetHashCode(), this);
 }
Exemplo n.º 2
0
 public void DoMove(UTTTMove move)
 {
     // Set to 1 / 2 depending on player
     field[move.x, move.y] = (activePlayer ? 1 : 2);
     hashCode = zobristHasher.getNewHashcode(hashCode, new Tuple <int, int>(move.x, move.y), activePlayer ? 1 : 0);
     UpdateState(move);
 }
Exemplo n.º 3
0
        public void UpdateState(UTTTMove move)
        {
            // Check fields for winner
            CheckField(move.x / 3 + move.y / 3 * 3);

            // Check macro for winner
            CheckMacro();

            // Alternate active player
            activePlayer ^= true;
        }
        // Finds a copy of a Move in a list of Moves, then swaps the found copy with another given move
        private void FindCopyAndSwap(UTTTMove toFind, List <UTTTMove> moves, UTTTMove toSwapWith)
        {
            UTTTMove moveCopy = null;

            foreach (UTTTMove move in moves)
            {
                if (move.Equals(toFind))
                {
                    moveCopy = move;
                    break;
                }
            }
            if (moveCopy == null)
            {
                return;
            }
            toFind     = toSwapWith;
            toSwapWith = moveCopy;
        }
        // Returns the best move from some particular state for the player which has the turn, within the time given
        // Returns random move if not enough time is given
        // pre: startState != null && !startState.isFinal()
        public UTTTMove FindBestMove(UTTTState startState, int msGiven)
        {
            if (startState == null || startState.IsFinal())
            {
                throw new ArgumentException("TimedSearcher.FindBestMove: Invalid startState passed.");
            }

            // stopwatch keeps track of how much time we have left
            Stopwatch sw = new Stopwatch();

            sw.Start();

            // iterative deepening
            UTTTMove          bestMove  = null;
            double            bestScore = 0;
            TimedAlphaBetaWIP timedAB   = new TimedAlphaBetaWIP(sw, msGiven, startState);

            for (int depthLeft = 1; sw.ElapsedMilliseconds < msGiven; depthLeft++)
            {
                List <UTTTMove> newMoveList = new List <UTTTMove>();
                TimedAlphaBetaWIP.AlphaBetaIterationResult res = timedAB.computeNextIteration();
                if (res.outOfTime)
                {
                    break;
                }
                else
                {
                    bestMove  = res.bestMove;
                    bestScore = res.bestMoveValue;
                }
            }

            // if no time to find any move, return random move
            if (bestMove == null)
            {
                bestMove = startState.GetPossibleMoves().First();
            }

            sw.Stop();
            Console.Error.WriteLine(bestScore);
            return(bestMove);
        }
Exemplo n.º 6
0
        // Generate state from given engine string
        // Generally always used to parse
        public UTTTState(String fieldString, String macroString, ZobristHasher zobristHasher, bool weArePlayerOne)
        {
            String[] fieldArray = fieldString.Split(',');
            for (int i = 0; i != 81; i++)
            {
                field[i % 9, i / 9] = Int32.Parse(fieldArray[i]);
            }

            String[] macroArray = macroString.Split(',');
            for (int i = 0; i != 9; i++)
            {
                macro[i % 3, i / 3] = Int32.Parse(macroArray[i]);
            }

            for (int i = 0; i != 81; i++)
            {
                moveArray[i % 9, i / 9] = new UTTTMove(i % 9, i / 9);
            }

            //Our turn
            playerNum          = (weArePlayerOne ? 1 : 2);
            this.zobristHasher = zobristHasher;
            this.hashCode      = zobristHasher.getOriginalHashcode();
        }
Exemplo n.º 7
0
        private static void RealMainEatCheese()
        {
            TimedSearcher searcher      = new TimedSearcher();
            ZobristHasher zobristHasher = new ZobristHasher(9, 9, 2);
            UTTTState     currentState  = null;

            int    timePerMove;
            int    timebank;
            String field          = null;
            String macroboard     = null;
            bool   weArePlayerOne = false;

            while (true)
            {
                Thread.Sleep(10);
                String line = Console.In.ReadLine();
                if (line.Length == 0)
                {
                    continue;
                }
                Console.Error.WriteLine(line);
                String[] parts = line.Split(' ');
                switch (parts[0])
                {
                case "settings":
                    switch (parts[1])
                    {
                    case "time_per_move":
                        timePerMove = int.Parse(parts[2]);
                        break;

                    case "timebank":
                        timebank = int.Parse(parts[2]);
                        break;

                    case "field":
                        field = parts[2];
                        break;

                    case "macroboard":
                        macroboard = parts[2];
                        break;

                    case "your_botid":
                        weArePlayerOne = (int.Parse(parts[2]) == 1);
                        break;
                    }
                    break;

                case "update":
                    switch (parts[2])
                    {
                    case "field":
                        field = parts[3];
                        break;

                    case "macroboard":
                        macroboard = parts[3];
                        break;
                    }
                    break;

                case "action":
                    currentState = new UTTTState(field, macroboard, zobristHasher, weArePlayerOne);
                    UTTTMove chosen = searcher.FindBestMove(currentState, 2000);
                    Console.WriteLine($"place_move {chosen.x} {chosen.y}");
                    Console.Out.Flush();
                    break;

                default:
                    // error
                    break;
                }
            }
        }
        // state        : The root of the (sub)-tree this search expands
        // alpha        : Value used for AlphaBeta pruning - maximum value maximizing player can definitely get
        // beta         : Value used for AlphaBeta pruning - minimum value minimizing player can definitely get
        // depthLeft    : How many more depths we are allowed to explore
        private double AlphaBetaSearch(UTTTState state, double alpha, double beta, int depthLeft)
        {
            // throw an exception if our player is forced to stop
            if (sw.ElapsedMilliseconds > msGiven)
            {
                throw new OutOfTimeException();
            }

            // if final depth reached, then return the value of this leaf
            if (depthLeft == 0 || state.IsFinal())
            {
                return(state.Evaluate());
            }

            // if not final depth, then generate all possible branches
            List <UTTTMove> moves = state.GetPossibleMoves();

            //
            if (moves.Count == 0)
            {
                throw new OutOfTimeException();
            }

            // if only a single move is possible, don't decrease depth
            if (moves.Count == 1)
            {
                depthLeft++;
            }

            // if the state has been seen before, then continue
            // tracing the best move of the previous iteration by putting the old move
            // in the first position to be evaluated. This leads to better pruning.
            StateRecord rec = null;

            statesSeen.TryGetValue(state.GetHashCode(), out rec);
            if (rec != null)
            {
                if (rec.iteration == iteration)
                {
                    return(rec.value);
                }
                if (rec.bestMove != null)
                {
                    FindCopyAndSwap(rec.bestMove, moves, moves.First());
                }
                statesSeen.Remove(state.GetHashCode());
            }
            else
            {
                rec = new StateRecord();
            }

            // keep track of the best move
            // update the StateRecord in the dictionary after we have finished analyzing the state
            Boolean  min      = state.MinimizingHasTurn();
            UTTTMove bestMove = null;

            foreach (UTTTMove move in moves)
            {
                state.DoMove(move);
                double result = AlphaBetaSearch(state, alpha, beta, depthLeft - 1);
                state.UndoMove(move);
                if ((min && result < beta) || (!min && result > alpha))
                {
                    bestMove = move;
                    if (min)
                    {
                        beta = result;
                    }
                    else
                    {
                        alpha = result;
                    }
                }
                if (alpha >= beta)
                {
                    // update record and return
                    double res = (alpha + beta) / 2;
                    rec.Update(res, bestMove, state, statesSeen, iteration);
                    return(res);
                }
            }
            // update record and return
            if (min)
            {
                rec.Update(beta, bestMove, state, statesSeen, iteration);
                return(beta);
            }
            else
            {
                rec.Update(alpha, bestMove, state, statesSeen, iteration);
                return(alpha);
            }
        }
Exemplo n.º 9
0
 public void UndoMove(UTTTMove move)
 {
     field[move.x, move.y] = 0;
     hashCode = zobristHasher.getNewHashcode(hashCode, new Tuple <int, int> (move.x, move.y), activePlayer ? 0 : 1);
     UpdateState(move);
 }
Exemplo n.º 10
0
 public bool Equals(UTTTMove other)
 {
     return((other.x == this.x) && (other.y == this.y));
 }