Пример #1
0
        private bool Search(int i, int j, enPiece test_piece, ref bool bIsFound)
        {
            //terminate search, since not on board
            if (i < 0 || i >= m_size || j < 0 || j >= m_size)
            {
                return(false);
            }

            enPiece piece = m_board[i, j];

            //terminate search, since cell is empty
            if (piece == enPiece.Empty)
            {
                return(false);
            }

            //figure of the same color
            if (piece == test_piece)
            {
                bIsFound = true;
                return(false);
            }

            //continue
            return(true);
        }
Пример #2
0
        //Calculate all possible moves
        //this is INTERNAL function
        //1. the move coordinates should be on the board
        //2. board cell should be empty
        // this function does not check these things!!!
        private bool IsMoveLegal(int move_x, int move_y, enPiece piece)
        {
            //All Game Logic is here
            bool bIsFound;
            int  x, y, k;

            enPiece move_fig = piece;

            int nCount;

            for (k = 0; k < m_nTotalDir; k++)
            {
                x = move_x + dx[k];
                y = move_y + dy[k];

                nCount   = 0;
                bIsFound = false;

                //move in that direction until (end of board || empty cell || same color figure)
                while (Search(x, y, move_fig, ref bIsFound))
                {
                    x += dx[k];
                    y += dy[k];
                    nCount++;
                }

                if (bIsFound && nCount != 0)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
        public Game(enPiece humanPlayer, int depth, bool bPerfectEnd)
        {
            m_bGameOver   = false;
            m_HumanPlayer = humanPlayer;
            m_depth       = depth;

            m_board   = new Board();
            m_vBoards = new LinkedList <Board>();

            m_vComputerPlayers = new Dictionary <enPiece, ComputerPlayer>();

            if (m_HumanPlayer == enPiece.Empty)
            {
                m_vComputerPlayers.Add(enPiece.White, new ComputerPlayerBalanced(enPiece.White, depth, 40, 16, 9, bPerfectEnd));
                m_vComputerPlayers.Add(enPiece.Black, new ComputerPlayerBalanced(enPiece.Black, depth, 30, 16, 9, bPerfectEnd));
            }
            else
            {
                enPiece piece = Board.FlipPiece(m_HumanPlayer);

                m_vComputerPlayers.Add(piece, new ComputerPlayerBalanced(piece, depth, 20, 1, 1, bPerfectEnd));
                //m_vComputerPlayers.Add(piece, new ComputerPlayerMasked(piece, depth, bPerfectEnd));
                //m_vComputerPlayers.Add(piece, new ComputerPlayerDeepSampler(piece));
            }
        }
Пример #4
0
        private bool MakeMove(Move move, bool bSaveBoard)
        {
            if (m_board.IsMoveLegal(move))
            {
                //Save board before the move
                if (bSaveBoard)
                {
                    m_vBoards.AddLast(new Board(m_board));
                }

                //Make move
                m_board.MakeMove(move);

                //Change player
                m_current_player = Board.FlipPiece(m_current_player);

                //store gameover flag
                m_bGameOver = m_board.State.GameOver;

                //if game is not over but current player has no moves then change the current player
                if (!m_bGameOver && !m_board.HasMoves(m_current_player))
                {
                    m_current_player = Board.FlipPiece(m_current_player);
                }
                m_lastMove = move;
                return(true);
            }
            else
            {
                return(false); //no moves were made
            }
        }
Пример #5
0
        private void aIGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (StreamWriter sw = new StreamWriter("ai.game.csv"))
            {
                sw.WriteLine(String.Format("{0}\t{1}\t{2}\t{3}\t{4}", "time", "count", "mobility_weight", "mask_weight", "count_weight"));

                System.Random rng = new Random();

                for (int i = 0; i < 1; i++)
                {
                    Dictionary <enPiece, ComputerPlayer> vComputerPlayers = new Dictionary <enPiece, ComputerPlayer>();

                    int mobility_weight = 41;
                    int mask_weight     = 4;
                    int count_weight    = 55;
                    int total_weigth    = mobility_weight + mask_weight + count_weight;

                    vComputerPlayers[enPiece.White] = new ComputerPlayerBalanced(enPiece.White, 5, 20, 1, 1, true);
                    // vComputerPlayers[enPiece.Black] = new ComputerPlayerMobility(enPiece.Black, 5);
                    vComputerPlayers[enPiece.Black] = new ComputerPlayerMasked(enPiece.Black, 5, true);

                    m_game = new Game(vComputerPlayers);

                    int   maxMoves   = 60;
                    int[] pos_delta  = new int[maxMoves];
                    int[] mov_delta  = new int[maxMoves];
                    int[] mask_score = new int[maxMoves];

                    int index = 0;
                    while (!m_game.Over)
                    {
                        m_game.Play();

                        if (index < maxMoves)
                        {
                            pos_delta[index] = (m_game.CurrentBoard.CountPieces(enPiece.White) - m_game.CurrentBoard.CountPieces(enPiece.Black));
                            mov_delta[index] = (m_game.CurrentBoard.CountMoves(enPiece.White) - m_game.CurrentBoard.CountMoves(enPiece.Black));
                            //mask_score[index] = (vComputerPlayers[enPiece.Black].MaskBasedScore(m_game.CurrentBoard));
                            index++;
                        }
                    }

                    enPiece winner = m_game.Winner;

                    int white_count = m_game.CurrentBoard.CountPieces(enPiece.White);
                    int black_count = m_game.CurrentBoard.CountPieces(enPiece.Black);

                    StringBuilder sb = new StringBuilder();

                    sb.Append(String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t", DateTime.Now, white_count - black_count, (double)mobility_weight / total_weigth, (double)mask_weight / total_weigth, (double)count_weight / total_weigth));
                    sb.Append("pos\t").Append(ListToString(pos_delta, "\t"));
                    sb.Append("mov\t").Append(ListToString(mov_delta, "\t"));
                    sb.Append("msk\t").Append(ListToString(mask_score, "\t"));

                    sw.WriteLine(sb.ToString());
                    sw.Flush();
                }
            }
        }
Пример #6
0
        public ComputerPlayer(enPiece piece, int nDepth, bool bPerfectFinish)
            : base(piece)
        {
            m_nDepth = nDepth;

            m_timer = new HRTimer();

            m_bPerfectFinish = bPerfectFinish;
        }
Пример #7
0
        /// <summary>
        /// Reset to default
        /// </summary>
        public void Reset()
        {
            m_nDepth          = 5;
            m_board_color     = Color.FromArgb(32, 121, 16);
            m_hint_color      = Color.FromArgb(16, 60, 8);
            m_last_move_color = Color.FromArgb(0, 200, 250);

            m_player = enPiece.White;
            m_bShowAvailableMoves = true;
            m_bShowLastMove       = true;
            m_bPerfectEnding      = true;
        }
Пример #8
0
 public static enPiece FlipPiece(enPiece piece)
 {
     if (piece == enPiece.White)
     {
         return(enPiece.Black);
     }
     else if (piece == enPiece.Black)
     {
         return(enPiece.White);
     }
     else
     {
         return(piece);
     }
 }
Пример #9
0
        public int CountPieces(enPiece piece)
        {
            int nCount = 0;

            for (int i = 0; i < m_size; i++)
            {
                for (int j = 0; j < m_size; j++)
                {
                    if (m_board[i, j] == piece)
                    {
                        nCount++;
                    }
                }
            }
            return(nCount);
        }
Пример #10
0
 //check if there are any moves available
 public bool HasMoves(enPiece piece)
 {
     for (int i = 0; i < m_size; i++)
     {
         for (int j = 0; j < m_size; j++)
         {
             if (m_board[i, j] == enPiece.Empty)
             {
                 if (IsMoveLegal(i, j, piece))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
Пример #11
0
 public ComputerPlayerMasked(enPiece piece, int nDepth, bool bPerfectFinish)
     : base(piece, nDepth, bPerfectFinish)
 {
     //mask table was taken from http://samsoft.org.uk/reversi/
     //used by Microsoft in their reversi program
     //Sum of all elements is 352
     m_vMask = new int[, ] {
         { 99, -8, 8, 6, 6, 8, -8, 99 },
         { -8, -24, -4, -3, -3, -4, -24, -8 },
         { 8, -4, 7, 4, 4, 7, -4, 8 },
         { 6, -3, 4, 0, 0, 4, -3, 6 },
         { 6, -3, 4, 0, 0, 4, -3, 6 },
         { 8, -4, 7, 4, 4, 7, -4, 8 },
         { -8, -24, -4, -3, -3, -4, -24, -8 },
         { 99, -8, 8, 6, 6, 8, -8, 99 },
     };
 }
Пример #12
0
        //count available moves
        public int CountMoves(enPiece piece)
        {
            int nCount = 0;

            for (int i = 0; i < m_size; i++)
            {
                for (int j = 0; j < m_size; j++)
                {
                    if (m_board[i, j] == enPiece.Empty)
                    {
                        if (IsMoveLegal(i, j, piece))
                        {
                            nCount++;
                        }
                    }
                }
            }
            return(nCount);
        }
Пример #13
0
        public List <Move> GetAvailableMoves(enPiece piece)
        {
            List <Move> vMoves = new List <Move>();

            for (int i = 0; i < m_size; i++)
            {
                for (int j = 0; j < m_size; j++)
                {
                    if (m_board[i, j] == enPiece.Empty)
                    {
                        if (IsMoveLegal(i, j, piece))
                        {
                            vMoves.Add(new Move(i, j, piece));
                        }
                    }
                }
            }
            return(vMoves);
        }
Пример #14
0
        private void UpdatedStatus()
        {
            if (m_game.Over)
            {
                enPiece winner = m_game.Winner;

                if (winner != enPiece.Empty)
                {
                    this.toolStripStatusLabel1.Text = winner.ToString() + " won!";
                }
                else
                {
                    this.toolStripStatusLabel1.Text = "the game is a draw!";
                }

                //Save finished game
                if (!m_statistics.Games.ContainsValue(m_game) && !m_game.Saved)
                {
                    m_statistics.Games.Add(DateTime.Now, m_game);
                    m_game.Saved = true;

                    //this.backgroundWorker1.RunWorkerAsync();
                }
            }
            else
            {
                this.toolStripStatusLabel1.Text = "Next Move: " + m_game.CurrentPlayer.ToString();
            }

            string score = String.Empty;

            score += " White: " + m_game.CurrentBoard.CountPieces(enPiece.White) + " ";
            score += " Black: " + m_game.CurrentBoard.CountPieces(enPiece.Black) + " ";

            this.toolStripStatusLabel1.Text += "  (" + score + ")";
        }
Пример #15
0
 public ComputerPlayerCount(enPiece piece, int nDepth, bool bPerfectFinish)
     : base(piece, nDepth, bPerfectFinish)
 {
 }
Пример #16
0
        private int minimax_ab_advanced(Node node, int nAlpha, int nBeta)
        {
            node.alpha = nAlpha;
            node.beta  = nBeta;

            BoardState state = node.board.State;

            //check if this is the last node
            if (node.depth > m_nMinMaxDepth || state.GameOver)
            {
                m_nMinMaxCount++;
                return(GetHeuristic(node.board, state));
            }
            else
            {
                //if node is white and there are no moves for white change node to black
                if (node.max && !state.WhiteMoves)
                {
                    node.max = false;
                }

                //if node is black and there are no moves for black change node to white
                if (!node.max && !state.BlackMoves)
                {
                    node.max = true;
                }
                //calculate all posible moves
                int nResult;

                //Create new node and copy all node moves
                Node new_node;
                new_node.depth = node.depth + 1;
                new_node.alpha = node.alpha;
                new_node.beta  = node.beta;

                //Get Positions From the Board
                enPiece piece = node.max ? enPiece.White : enPiece.Black;

                List <Move> vMoves = node.board.GetAvailableMoves(piece);

                //Cycle over ALL new nodes
                foreach (Move move in vMoves)
                {
                    new_node.max   = !node.max;
                    new_node.board = (Board)node.board.Clone();
                    new_node.board.MakeBlindMove(move);

                    nResult = minimax_ab_advanced(new_node, node.alpha, node.beta);

                    if (node.max)
                    {
                        //max node Alpha = max(Alpha, Result)
                        if (node.alpha < nResult)
                        {
                            node.alpha = nResult;
                        }
                        //Beta is the rating of the best move from min perspective
                        //min will choose move with Beta thus if our Alpha is higher then he will never let us play this move
                        if (node.beta <= node.alpha)
                        {
                            return(node.alpha);
                        }
                    }
                    else
                    {
                        //min node Beta = min(Beta, Result)
                        if (node.beta > nResult)
                        {
                            node.beta = nResult;
                        }
                        //Cut off
                        if (node.beta <= node.alpha)
                        {
                            return(node.beta);
                        }
                    }
                }//end of cycle
                return(node.max ? node.alpha : node.beta);
            }
        }
Пример #17
0
 public ComputerPlayerMobility(enPiece piece, int nDepth)
     : base(piece, nDepth, true)
 {
 }
Пример #18
0
 public HumanPlayer(enPiece piece)
     : base(piece)
 {
 }
Пример #19
0
 public ComputerPlayer(enPiece piece)
     : this(piece, 4, true)
 {
 }
Пример #20
0
 public Player(enPiece piece)
 {
     m_piece = piece;
 }
Пример #21
0
 public ComputerPlayer3rd(enPiece piece, int nDepth)
     : base(piece, nDepth, true)
 {
 }
Пример #22
0
 public ComputerPlayerBalanced(enPiece piece)
     : this(piece, 4, 20, 1, 1, true)
 {
 }
Пример #23
0
 public Move(Move move)
 {
     m_piece = move.m_piece;
     m_to    = move.m_to;
 }
Пример #24
0
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Rectangle rect = pictureBox1.DisplayRectangle;

            rect.Height--;
            rect.Width--;
            g.DrawRectangle(Pens.Black, rect);

            rect.Inflate(-m_nMargin, -m_nMargin);

            int nSize = m_game.CurrentBoard.Size;


            //show available moves
            if (m_settings.ShowAvailableMoves)
            {
                List <Move> vMoves = m_game.CurrentBoard.GetAvailableMoves(m_game.CurrentPlayer);

                foreach (Move move in vMoves)
                {
                    g.FillRectangle(m_hint_brush, new Rectangle(rect.Left + move.To.X * m_nCellSize, rect.Top + move.To.Y * m_nCellSize, m_nCellSize, m_nCellSize));
                }
            }

            //show pieces
            for (int i = 0; i < nSize; i++)
            {
                for (int j = 0; j < nSize; j++)
                {
                    enPiece piece = m_game.CurrentBoard[i, j];

                    if (m_vPieceImage.ContainsKey(piece))
                    {
                        Bitmap image = m_vPieceImage[piece];
                        g.DrawImage(image, rect.Left + i * m_nCellSize, rect.Top + j * m_nCellSize, image.Width, image.Height);
                    }
                }
            }


            //show last move
            if (m_settings.ShowLastMove)
            {
                Move move = m_game.LastMove;

                if (move != null)
                {
                    Rectangle last_move_rect = new Rectangle(rect.Left + move.To.X * m_nCellSize + 2, rect.Top + move.To.Y * m_nCellSize + 2, 5, 5);
                    g.FillEllipse(m_last_move_brush, last_move_rect);
                    g.DrawEllipse(Pens.Black, last_move_rect);
                }
            }

            //Draw Grid
            for (int i = 0; i <= nSize; i++)
            {
                g.DrawLine(Pens.Black, rect.Left + i * m_nCellSize, rect.Bottom, rect.Left + i * m_nCellSize, rect.Top);
                g.DrawLine(Pens.Black, rect.Left, rect.Top + i * m_nCellSize, rect.Right, rect.Top + i * m_nCellSize);
            }

            //Draw markers
            int[] vMarkers = new int[] { 2, 6 };

            for (int i = 0; i < vMarkers.Length; i++)
            {
                for (int j = 0; j < vMarkers.Length; j++)
                {
                    Rectangle marker_rect = new Rectangle(rect.Left + vMarkers[i] * m_nCellSize - 2, rect.Top + vMarkers[j] * m_nCellSize - 2, 4, 4);
                    g.FillEllipse(m_marker_brush, marker_rect);
                    g.DrawEllipse(Pens.Black, marker_rect);
                }
            }

            if (m_game.Over)
            {
                Font    message_font = new Font(FontFamily.GenericSansSerif, 0.7f * (float)m_nCellSize, FontStyle.Bold);
                enPiece winner       = m_game.Winner;

                string game_status = winner != enPiece.Empty ? (winner == m_game.HumanPlayer ? "You Won!" : "Computer Won!") : "the game is a draw!";

                g.DrawString(game_status, message_font, Brushes.Red, rect.Left, rect.Top);
            }
        }
Пример #25
0
 public Move(int i, int j, enPiece piece)
     : this(new Position(i, j), piece)
 {
 }
Пример #26
0
 public Move(Position to, enPiece piece)
 {
     m_piece = piece;
     m_to    = to;
 }
Пример #27
0
 public ComputerPlayerRandom(enPiece piece)
     : base(piece, 1, false)
 {
 }
Пример #28
0
 public ComputerPlayerCombination(enPiece piece, int depth)
     : base(piece, depth, false)
 {
 }