有AI的重力四子棋

这里展示了一个有AI的重力四子棋的C#程序。 AI采用alpha beta剪枝的方法。


界面代码MainWindow.xaml:


    
        


逻辑代码ManWindow.xaml.cs:

/*
 * This program is a gravity connect four game. AI uses the alpha beta pruning search.
 * */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms;

namespace ConnectFour
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        private const int column = 4;           // The column of chess board
        private const int row = 5;              // The row of chess board
        private const bool HUMAN = true;        // Human turn
        private const bool PROGRAM = false;     // Program turn

        private bool player = HUMAN;

        private double width;
        private double height;
        private double gridWidth;
        private double gridHeight;

        private int maxDepth = 10;
        private bool canClick = true;

        private Position board = new Position();

        private int nodeNumber = 0;
        private int maxCut = 0;
        private int minCut = 0;

        public MainWindow()
        {
            InitializeComponent();
            AddHandler(FrameworkElement.PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(ChessBorad_MouseLeftButtonDown), true);
            AddHandler(FrameworkElement.PreviewMouseRightButtonDownEvent, new MouseButtonEventHandler(ChessBorad_MouseRightButtonDown), true);
        }

        private void DrawChessBoard()
        {
            chessBoard.Children.Clear();

            width = chessBoard.ActualWidth;
            height = chessBoard.ActualHeight;
            gridWidth = width * 0.9 / column;
            gridHeight = height * 0.9 / row;

            for (int i = 0; i <= row; i++)
            {
                DrawingLine(width * 0.05, height * 0.05 + i * gridHeight, width * 0.95, height * 0.05 + i * gridHeight);
            }

            for (int i = 0; i <= column; i++)
            {
                DrawingLine(width * 0.05 + i * gridWidth, height * 0.05, width * 0.05 + i * gridWidth, height * 0.95);
            }

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < column; j++)
                {
                    if (board.chess[i, j] == Position.HUMAN_CHESS)
                        DrawingEllipse(gridWidth * 0.9, gridHeight * 0.9, width * 0.05 + j * gridWidth + 0.5 * gridWidth, height * 0.05 + i * gridHeight + 0.5 * gridHeight, HUMAN);
                    else if (board.chess[i, j] == Position.PROGRAM_CHESS)
                        DrawingEllipse(gridWidth * 0.9, gridHeight * 0.9, width * 0.05 + j * gridWidth + 0.5 * gridWidth, height * 0.05 + i * gridHeight + 0.5 * gridHeight, PROGRAM);
                }
            }
        }

        protected void DrawingLine(double x1, double y1, double x2, double y2)
        {
            Line myLine = new Line();
            myLine.Stroke = System.Windows.Media.Brushes.Black;
            myLine.X1 = x1;
            myLine.Y1 = y1;
            myLine.X2 = x2;
            myLine.Y2 = y2;
            myLine.StrokeThickness = 1;

            chessBoard.Children.Add(myLine);
        }

        protected void DrawingEllipse(double widthEllipse, double heightEllipse, double centerX, double centerY, bool currentPlayer)
        {
            Ellipse myEllipse = new Ellipse();
            if (currentPlayer) myEllipse.Stroke = System.Windows.Media.Brushes.DarkBlue;
            else myEllipse.Stroke = System.Windows.Media.Brushes.Red;

            myEllipse.Width = widthEllipse;
            myEllipse.Height = heightEllipse;
            myEllipse.StrokeThickness = 2;
            myEllipse.Fill = myEllipse.Stroke;

            myEllipse.Margin = new Thickness(centerX - widthEllipse / 2, centerY - heightEllipse / 2, 0, 0);

            chessBoard.Children.Add(myEllipse);
        }

        private bool isInChessBoundary(double x, double y)
        {
            return x >= chessBoard.ActualWidth * 0.05 && x <= chessBoard.ActualWidth * 0.95 && y >= chessBoard.ActualHeight * 0.05 && y <= chessBoard.ActualHeight * 0.95;
        }

        private void ConnectFourForm_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            DrawChessBoard();
        }

        private void ChessBorad_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!canClick) return;
            Point mousePosition = e.GetPosition(chessBoard);
            double x = mousePosition.X;
            double y = mousePosition.Y;
            if (!isInChessBoundary(x, y)) return;
            int columnIndex = (int)((x - width * 0.05) / gridWidth);
            bool canNext = mouseLeftClickedInColumn(columnIndex);
            DrawChessBoard();
            testEndOfGame();
            if (canNext)
            {
                player = PROGRAM;
                programTurn();
                testEndOfGame();
            }
            e.Handled = true;
        }

        private void ChessBorad_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!canClick) return;
            Point mousePosition = e.GetPosition(chessBoard);
            double x = mousePosition.X;
            double y = mousePosition.Y;
            if (!isInChessBoundary(x, y)) return;
            int columnIndex = (int)((x - width * 0.05) / gridWidth);
            bool canNext = mouseRightClickedInColumn(columnIndex);
            DrawChessBoard();
            testEndOfGame();
            if (canNext)
            {
                player = PROGRAM;
                programTurn();
                testEndOfGame();
            }
            e.Handled = true;
        }

        private void testEndOfGame()
        {
            if(wonPosition(board, HUMAN)) {
                canClick = false;
                System.Windows.MessageBox.Show("Human won!");
                return;
            }
            else if(wonPosition(board, PROGRAM)) {
                canClick = false;
                System.Windows.MessageBox.Show("Program won!");
                return;
            }
            else if (drawnPosition(board))
            {
                canClick = false;
                System.Windows.MessageBox.Show("Draw game!");
                return;
            }
        }

        private void programTurn()
        {
            ArrayList v = alphaBeta(0, board, PROGRAM);
            board = (Position)v[1];
            DrawChessBoard();
            player = HUMAN;

            txbMessage.Text = "Node Number: " + nodeNumber + ", Max Cut Number: " + maxCut + ", Min Cut Number: " + minCut;
        }

        private bool mouseLeftClickedInColumn(int columnIndex)
        {
            int rowIndex = 0;
            if (isFullColumn(board.chess, columnIndex)) return false;
            if (isEmptyColumn(board.chess, columnIndex)) rowIndex = row - 1;
            else
            {
                for (int i = 0; i < row; i++)
                {
                    if (board.chess[i, columnIndex] != Position.EMPTY)
                    {
                        rowIndex = i - 1;
                        break;
                    }
                }
            }
            if (player == HUMAN) board.chess[rowIndex, columnIndex] = Position.HUMAN_CHESS;
            else board.chess[rowIndex, columnIndex] = Position.PROGRAM_CHESS;
            return true;
        }

        private bool mouseRightClickedInColumn(int columnIndex)
        {
            if (board.chess[row - 1, columnIndex] != Position.EMPTY)
            {
                if (player)
                {
                    if (board.chess[row - 1, columnIndex] != Position.HUMAN_CHESS) return false;
                }
                else
                {
                    if (board.chess[row - 1, columnIndex] != Position.PROGRAM_CHESS) return false;
                }
                for (int i = row - 1; i > 0; i--)
                    board.chess[i, columnIndex] = board.chess[i - 1, columnIndex];
                board.chess[0, columnIndex] = 0;
                return true;
            }
            return false;
        }

        //judge whether the column ie empty
        private static bool isEmptyColumn(short[,] aChess, int columnIndex)
        {
            for (int i = 0; i < aChess.GetLength(0); i++)
            {
                if (aChess[i, columnIndex] != Position.EMPTY) return false;
            }
            return true;
        }

        //judge whether the column is full
        private static bool isFullColumn(short[,] aChess, int columnIndex)
        {
            for (int i = 0; i < aChess.GetLength(0); i++)
            {
                if (aChess[i, columnIndex] == Position.EMPTY) return false;
            }
            return true;
        }

        // alpha beta pruning search
        private ArrayList alphaBeta(int depth, Position p, bool currentPlayer)
        {
            nodeNumber = 0;
            minCut = 0;
            maxCut = 0;
            ArrayList v = alphaBetaHelper(depth, p, currentPlayer, float.PositiveInfinity, float.NegativeInfinity);
            return v;
        }

        // The recursive method of alpha beta pruning search
        private ArrayList alphaBetaHelper(int depth, Position p, bool currentPlayer, float alpha, float beta)
        {
            nodeNumber++;
            if (reachedMaxDepth(p, depth))
            {
                ArrayList v = new ArrayList(2);
                float value = positionEvaluation(p, currentPlayer);
                v.Add(value);
                v.Add(null);
                return v;
            }
            ArrayList best = new ArrayList();
            Position[] moves = possibleMoves(p, currentPlayer);
            for (int i = 0; i < moves.GetLength(0); i++)
            {
                ArrayList v2 = alphaBetaHelper(depth + 1, moves[i], !currentPlayer, -beta, -alpha);
                float value = -(float)v2[0];
                if (value > beta)
                {
                    beta = value;
                    best = new ArrayList();
                    best.Add(moves[i]);
                    IEnumerator enum2 = v2.GetEnumerator();
                    enum2.MoveNext(); // skip previous value
                    while (enum2.MoveNext())
                    {
                        Object o = enum2.Current;
                        if (o != null) best.Add(o);
                    }
                }
                /**
                 * Use the alpha-beta cutoff test to abort search if we
                 * found a move that proves that the previous move in the
                 * move chain was dubious
                 */
                if (beta >= alpha)
                {
                    if (currentPlayer == player)
                        maxCut++;
                    else
                        minCut++;
                    break;
                }
            }
            ArrayList v3 = new ArrayList();
            v3.Add(beta);
            IEnumerator enum3 = best.GetEnumerator();
            while (enum3.MoveNext())
            {
                v3.Add(enum3.Current);
            }
            return v3;
        }

        private bool drawnPosition(Position p)
        {
            Position position = p;
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < column; j++)
                {
                    if (position.chess[i, j] == Position.EMPTY)
                        return false;
                }
            }
            return true;
        }

        private Position[] possibleMoves(Position pos, bool player)
        {
            int count = 0;
            for (int j = 0; j < column; j++)
            {
                if (!isFullColumn(pos.chess, j)) count++;
            }

            for (int j = 0; j < column; j++)
            {
                if (!isEmptyColumn(pos.chess, j))
                {
                    int indexRow = row - 1;
                    if (pos.chess[indexRow, j] == Position.HUMAN_CHESS && player == HUMAN) count++;
                    if (pos.chess[indexRow, j] == Position.PROGRAM_CHESS && player == PROGRAM) count++;
                }
            }

            Position[] ret = new Position[count];
            count = 0;
            for (int j = 0; j < column; j++)
            {
                if (!isFullColumn(pos.chess, j))
                {
                    Position pos2 = new Position();
                    pos2.chess = getNewArray(pos.chess);
                    int indexRow = 0;
                    if (isEmptyColumn(pos.chess, j)) indexRow = row - 1;
                    else
                    {
                        for (int i = 0; i < row; i++)
                        {
                            if (pos.chess[i, j] != Position.EMPTY)
                            {
                                indexRow = i;
                                break;
                            }
                        }
                        indexRow--;
                    }
                    if (player) pos2.chess[indexRow, j] = Position.HUMAN_CHESS;
                    else pos2.chess[indexRow, j] = Position.PROGRAM_CHESS;
                    ret[count++] = pos2;
                }
            }

            for (int j = 0; j < column; j++)
            {
                if (!isEmptyColumn(pos.chess, j))
                {
                    int row = pos.chess.GetLength(0) - 1;
                    if ((pos.chess[row, j] == Position.HUMAN_CHESS && player == HUMAN) || (pos.chess[row, j] == Position.PROGRAM_CHESS && player == PROGRAM))
                    {
                        Position pos2 = new Position();
                        pos2.chess = getNewArray(pos.chess);
                        for (int i = pos2.chess.GetLength(0) - 1; i > 0; i--)
                        {
                            pos2.chess[i, j] = pos2.chess[i - 1, j];
                        }
                        pos2.chess[0, j] = 0;
                        ret[count++] = pos2;
                    }
                }
            }
            return ret;
        }

        private bool reachedMaxDepth(Position p, int depth)
        {
            // TODO Auto-generated method stub
            bool ret = false;
            if (wonPosition(p, false)) ret = true;
            else if (wonPosition(p, true)) ret = true;
            else if (drawnPosition(p)) ret = true;
            else if (depth >= maxDepth) ret = true;
            return ret;
        }

        private bool wonPosition(Position pos, bool player)
        {
            int b;
            if (player) b = Position.HUMAN_CHESS;
            else b = Position.PROGRAM_CHESS;

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < column; j++)
                {
                    if (j + 3 < column)
                        if (pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i, j + 1] && pos.chess[i, j] == pos.chess[i, j + 2] && pos.chess[i, j] == pos.chess[i, j + 3]) return true;
                    if (i + 3 < row)
                        if (pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i + 1, j] && pos.chess[i, j] == pos.chess[i + 2, j] && pos.chess[i, j] == pos.chess[i + 3, j]) return true;
                    if (i + 3 < row && j + 3 < column)
                        if (pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i + 1, j + 1] && pos.chess[i, j] == pos.chess[i + 2, j + 2] && pos.chess[i, j] == pos.chess[i + 3, j + 3]) return true;
                    if (i + 3 < row && j - 3 >= 0)
                        if (pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i + 1, j - 1] && pos.chess[i, j] == pos.chess[i + 2, j - 2] && pos.chess[i, j] == pos.chess[i + 3, j - 3]) return true;
                }
            }
            return false;
        }

        private short[,] getNewArray(short[,] aChess)
        {
            short[,] newArray = new short[aChess.GetLength(0), aChess.GetLength(1)];

            for (int i = 0; i < aChess.GetLength(0); i++)
                for (int j = 0; j < aChess.GetLength(1); j++)
				newArray[i, j] = aChess[i, j];
		    return newArray;
	    }

        private float positionEvaluation(Position pos, bool player) 
        {
		// TODO Auto-generated method stub
		    if (wonPosition(pos, player))  {
            return float.PositiveInfinity;
            }
            if (wonPosition(pos, !player))  {
                return float.NegativeInfinity;
            }
        
		    int ret= 0;
		
		    int myChessman;
		    int enemyChessman;
		    if(player) {
			    myChessman = Position.HUMAN_CHESS;
			    enemyChessman = Position.PROGRAM_CHESS;
		    }
		    else {
			    myChessman = Position.PROGRAM_CHESS;
			    enemyChessman = Position.HUMAN_CHESS;
		    }
		
		    int[] myConnect3 = connect3(pos, player);
		    int[] enemyConnect3 = connect3(pos , !player);
		    int[] myConnect2 = connect2(pos, player);
		    int[] enemyConnect2 = connect2(pos, !player);
		
		    for(int i = 0; i < board.chess.GetLength(0); i++) {
			    for(int j = 0; j < board.chess.GetLength(1); j++) {
				    if(board.chess[i, j] == myChessman)
					    ret += 5;
				    else if(board.chess[i, j] == enemyChessman)
					    ret -= 5;
			    }
		    }
		
		    //evaluation function
		    ret += (myConnect2[1] * 30 + myConnect2[2] * 50);
            ret += (myConnect2[0] - myConnect2[1] - myConnect2[2]) * 15;
            ret -= (enemyConnect2[0] - enemyConnect2[1] - enemyConnect2[2]) * 15;
		    ret -= (enemyConnect2[1] * 30 + enemyConnect2[2] * 50);
            ret += (myConnect3[0] - myConnect3[1] - myConnect3[2]) * 50;
            ret -= (enemyConnect3[0] - enemyConnect3[1] - enemyConnect3[2]) * 50;
		    ret += myConnect3[1] * 100;
		    ret -= enemyConnect3[1] * 100;
		
		    return ret;
	    }

        private int[] connect2(Position pos, bool player)
        {
        	short b;
        	if(player) b = Position.HUMAN_CHESS;
        	else b = Position.PROGRAM_CHESS;
    	
    	    int[] n = {0, 0, 0};
    	
    	    for(int i = 0; i < pos.chess.GetLength(0); i++) {
    		    for(int j = 0; j < pos.chess.GetLength(1); j++) {
                    if (i + 1 < pos.chess.GetLength(0))
                    {
    	    		    if(pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i+1, j]) {
    	    			    while(true) {
                                if (i + 2 < pos.chess.GetLength(0))
        	    				    if(pos.chess[i+2, j] == b) break;
            	    			if(i-1 >= 0)
            	    				if(pos.chess[i-1, j] == b) break;
            	    			n[0]++;

                                if (i - 1 >= 0 && i + 2 >= pos.chess.GetLength(0))
                                {
        	    	    			if(pos.chess[i-1, j] == Position.EMPTY)
        	    		    			n[1]++;
        	    			    }
                                else if (i - 1 < 0 && i + 2 < pos.chess.GetLength(0))
                                {
        	    				    if(pos.chess[i+2, j] == Position.EMPTY)
        	    					    n[1]++;
        	    			    }
                                else if (i - 1 >= 0 && i + 2 < pos.chess.GetLength(0))
                                {
        	    				    if(pos.chess[i-1, j] == Position.EMPTY && pos.chess[i+2, j] != Position.EMPTY)
        	    					    n[1]++;
        	    				    if(pos.chess[i+2, j] == Position.EMPTY && pos.chess[i-1, j] != Position.EMPTY)
        	    					    n[1]++;
        	    				    if(pos.chess[i-1, j] == Position.EMPTY && pos.chess[i+2, j] == Position.EMPTY)
        	    					    n[2]++;
        	    			    }
        	    			    break;
    	    			    }
    	    		    }
    	    	    }

                    if (j + 1 < pos.chess.GetLength(1))
                    {
    				    if(pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i, j+1]) {
    					    while(true) {
                                if (j + 2 < pos.chess.GetLength(1))
        						    if(pos.chess[i, j+2] == b) break;
        	    			    if(j-1 >= 0)
        	    				    if(pos.chess[i, j-1] == b) break;
        					    n[0]++;

                                if (j - 1 >= 0 && j + 2 >= pos.chess.GetLength(1))
                                {
        						    if(pos.chess[i, j-1] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if (j - 1 < 0 && j + 2 < pos.chess.GetLength(1))
                                {
        						    if(pos.chess[i, j+2] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if (j - 1 >= 0 && j + 2 < pos.chess.GetLength(1))
                                {
        						    if(pos.chess[i, j-1] == Position.EMPTY && pos.chess[i, j+2] != Position.EMPTY)
        	    					    n[1]++;
        	    				    if(pos.chess[i, j+2] == Position.EMPTY && pos.chess[i, j-1] != Position.EMPTY)
        	    					    n[1]++;
        	    				
        	    				    if(pos.chess[i, j-1] == Position.EMPTY && pos.chess[i, j+2] == Position.EMPTY)
        	    					    n[2]++;
        					    }
        					    break;
    					    }
    				    }
    			    }

                    if (i + 1 < pos.chess.GetLength(0) && j + 1 < pos.chess.GetLength(1))
                    {
    				    if(pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i+1, j+1]) {
    					    while(true) {
                                if (i + 2 < pos.chess.GetLength(0) && j + 2 < pos.chess.GetLength(1))
        						    if(pos.chess[i+2, j+2] == b) break;
        					    if(i-1 >= 0 && j-1 >= 0) 
        						    if(pos.chess[i-1, j-1] == b) break;
        					    n[0]++;

                                if ((i - 1 >= 0 && j - 1 >= 0) && (i + 2 >= pos.chess.GetLength(0) || j + 2 >= pos.chess.GetLength(1)))
                                {
        						    if(pos.chess[i-1, j-1] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if ((i - 1 < 0 || j - 1 < 0) && (i + 2 < pos.chess.GetLength(0) && j + 2 < pos.chess.GetLength(1)))
                                {
        						    if(pos.chess[i+2, j+2] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if ((i - 1 >= 0 && j - 1 >= 0) && (i + 2 < pos.chess.GetLength(0) && j + 2 < pos.chess.GetLength(1)))
                                {
        						    if(pos.chess[i-1, j-1] == Position.EMPTY && pos.chess[i+2, j+2] != Position.EMPTY)
        							    n[1]++;
        						    if(pos.chess[i+2, j+2] == Position.EMPTY && pos.chess[i-1, j-1] != Position.EMPTY)
        							    n[1]++;
        						    if(pos.chess[i-1, j-1] == Position.EMPTY && pos.chess[i+2, j+2] == Position.EMPTY)
        							    n[2]++;
        					    }
        					    break;
    					    }
    				    }
    			    }
    			
    			    if(i-1 >= 0 && j+1 < pos.chess.GetLength(1)) {
    				    if(pos.chess[i, j] == b && pos.chess[i, j] == pos.chess[i-1, j+1]) {
    					    while(true) {
                                if (i - 2 >= 0 && j + 2 < pos.chess.GetLength(1))
        						    if(pos.chess[i-2, j+2] == b) break;
        					    if(i+1 < pos.chess.GetLength(0) && j-1 >= 0)
        						    if(pos.chess[i+1, j-1] == b) break;
        					    n[0]++;

                                if ((i - 2 >= 0 && j + 2 < pos.chess.GetLength(1)) && (i + 1 >= pos.chess.GetLength(0) || j - 1 < 0))
                                {
        						    if(pos.chess[i-2, j+2] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if ((i - 2 < 0 || j + 2 > pos.chess.GetLength(1)) && (i + 1 < pos.chess.GetLength(0) && j - 1 >= 0))
                                {
        						    if(pos.chess[i+1, j-1] == Position.EMPTY)
        							    n[1]++;
        					    }
                                else if ((i - 2 >= 0 && j + 2 < pos.chess.GetLength(1)) && (i + 1 < pos.chess.GetLength(0) && j - 1 >= 0))
                                {
        						    if(pos.chess[i-2, j+2] == Position.EMPTY && pos.chess[i+1, j-1] != Position.EMPTY)
        							    n[1]++;
        						    if(pos.chess[i+1, j-1] == Position.EMPTY && pos.chess[i-2, j+2] != Position.EMPTY)
        							    n[1]++;
        						    if(pos.chess[i-2, j+2] == Position.EMPTY && pos.chess[i+1, j-1] == Position.EMPTY)
        							    n[2]++;
        					    }
        					    break;
    					    }
    				    }
    			    }
    		    }
    	    }
    	    return n;
        }

        private int[] connect3(Position pos, bool player) {
    	short b;
    	if(player) b = Position.HUMAN_CHESS;
    	else b = Position.PROGRAM_CHESS;
    	
    	int[] n = {0, 0, 0};
    	
    	for(int i = 0; i < pos.chess.GetLength(0); i++) {
    		for(int j = 0; j < pos.chess.GetLength(1); j++) {
                if (i + 2 < pos.chess.GetLength(0))
                {
    	    		if(pos.chess[i, j] == b
    	    				&& pos.chess[i, j] == pos.chess[i+1, j]
    	    						&& pos.chess[i, j] == pos.chess[i+2, j]) {
    	    			while(true) {
    	    				if(i+3 < pos.chess.GetLength(0))
        	    				if(pos.chess[i+3, j] == b) break;
        	    			if(i-1 >= 0)
        	    				if(pos.chess[i-1, j] == b) break;
        	    			n[0]++;

                            if (i - 1 >= 0 && i + 3 >= pos.chess.GetLength(0))
                            {
        	    				if(pos.chess[i-1, j] == Position.EMPTY)
        	    					n[1]++;
        	    			}
        	    			else if(i-1 < 0 && i+3 < pos.chess.GetLength(0)) {
        	    				if(pos.chess[i+3, j] == Position.EMPTY)
        	    					n[1]++;
        	    			}
        	    			else if(i-1 >= 0 && i+3 < pos.chess.GetLength(0)) {
        	    				if(pos.chess[i-1, j] == Position.EMPTY 
        	    						&& pos.chess[i+3, j] != Position.EMPTY)
        	    					n[1]++;
        	    				if(pos.chess[i+3, j] == Position.EMPTY
        	    						&& pos.chess[i-1, j] != Position.EMPTY)
        	    					n[1]++;
        	    				
        	    				if(pos.chess[i-1, j] == Position.EMPTY
        	    						&& pos.chess[i+3, j] == Position.EMPTY)
        	    					n[2]++;
        	    			}
        	    			break;
    	    			}
    	    		}
    	    	}
    			
    			if(j+2 < pos.chess.GetLength(1)) {
    				if(pos.chess[i, j] == b
    						&& pos.chess[i, j] == pos.chess[i, j+1]
    								&& pos.chess[i, j] == pos.chess[i, j+2]) {
    					while(true) {
    						if(j+3 < pos.chess.GetLength(1))
        						if(pos.chess[i, j+3] == b) break;
        	    			if(j-1 >= 0)
        	    				if(pos.chess[i, j-1] == b) break;
        					n[0]++;
        					
        					if(j-1 >= 0 && j+3 >= pos.chess.GetLength(1)) {
        						if(pos.chess[i, j-1] == Position.EMPTY)
        							n[1]++;
        					}
        					else if(j-1 < 0 && j+3 < pos.chess.GetLength(1)) {
        						if(pos.chess[i, j+3] == Position.EMPTY)
        							n[1]++;
        					}
        					else if(j-1 >= 0 && j+3 < pos.chess.GetLength(1)) {
        						if(pos.chess[i, j-1] == Position.EMPTY 
        	    						&& pos.chess[i, j+3] != Position.EMPTY)
        	    					n[1]++;
        	    				if(pos.chess[i, j+3] == Position.EMPTY
        	    						&& pos.chess[i, j-1] != Position.EMPTY)
        	    					n[1]++;
        	    				
        	    				if(pos.chess[i, j-1] == Position.EMPTY
        	    						&& pos.chess[i, j+3] == Position.EMPTY)
        	    					n[2]++;
        					}
        					break;
    					}
    				}
    			}

                if (i + 2 < pos.chess.GetLength(0) && j + 2 < pos.chess.GetLength(1))
                {
    				if(pos.chess[i, j] == b
    						&& pos.chess[i, j] == pos.chess[i+1, j+1]
    								&& pos.chess[i, j] == pos.chess[i+2, j+2]) {
    					while(true) {
    						if(i+3 < pos.chess.GetLength(0) && j+3 < pos.chess.GetLength(1))
        						if(pos.chess[i+3, j+3] == b) break;
        					if(i-1 >= 0 && j-1 >= 0) 
        						if(pos.chess[i-1, j-1] == b) break;
        					n[0]++;
        					
        					if((i-1 >= 0 && j-1 >= 0) && (i+3 >= pos.chess.GetLength(0) || j+3 >= pos.chess.GetLength(1))) {
        						if(pos.chess[i-1, j-1] == Position.EMPTY)
        							n[1]++;
        					}
        					else if((i-1 < 0 || j-1 < 0) && (i+3 < pos.chess.GetLength(0) && j+3 < pos.chess.GetLength(1))) {
        						if(pos.chess[i+3, j+3] == Position.EMPTY)
        							n[1]++;
        					}
        					else if((i-1 >= 0 && j-1 >= 0) && (i+3 < pos.chess.GetLength(0) && j+3 < pos.chess.GetLength(1))) {
        						if(pos.chess[i-1, j-1] == Position.EMPTY
        								&& pos.chess[i+3, j+3] != Position.EMPTY)
        							n[1]++;
        						if(pos.chess[i+3, j+3] == Position.EMPTY
        								&& pos.chess[i-1, j-1] != Position.EMPTY)
        							n[1]++;
        						if(pos.chess[i-1, j-1] == Position.EMPTY && pos.chess[i+3, j+3] == Position.EMPTY)
        							n[2]++;
        					}
        					break;
    					}
    				}
    			}
    			
    			if(i-2 >= 0 && j+2 < pos.chess.GetLength(1)) {
    				if(pos.chess[i, j] == b
    						&& pos.chess[i, j] == pos.chess[i-1, j+1]
    								&& pos.chess[i, j] == pos.chess[i-2, j+2]) {
    					while(true) {
    						if(i-3 >= 0 && j+3 < pos.chess.GetLength(1))
        						if(pos.chess[i-3, j+3] == b) break;
        					if(i+1 < pos.chess.GetLength(0) && j-1 >= 0)
        						if(pos.chess[i+1, j-1] == b) break;
        					n[0]++;
        					
        					if((i-3 >= 0 && j+3 < pos.chess.GetLength(1)) && (i+1 >= pos.chess.GetLength(0) || j-1 < 0)) {
        						if(pos.chess[i-3, j+3] == Position.EMPTY)
        							n[1]++;
        					}
        					else if((i-3 < 0 || j+3 > pos.chess.GetLength(1)) && (i+1 < pos.chess.GetLength(0) && j-1 >= 0)) {
        						if(pos.chess[i+1, j-1] == Position.EMPTY)
        							n[1]++;
        					}
        					else if((i-3 >= 0 && j+3 < pos.chess.GetLength(1)) && (i+1 < pos.chess.GetLength(0) && j-1 >= 0)) {
        						if(pos.chess[i-3, j+3] == Position.EMPTY
        								&& pos.chess[i+1, j-1] != Position.EMPTY)
        							n[1]++;
        						if(pos.chess[i+1, j-1] == Position.EMPTY
        								&& pos.chess[i-3, j+3] != Position.EMPTY)
        							n[1]++;
        						if(pos.chess[i-3, j+3] == Position.EMPTY && pos.chess[i+1, j-1] == Position.EMPTY)
        							n[2]++;
        					}
        					break;
    					}
    				}
    			}
    		}
    	}
    	return n;
    }

        class Position
        {
            public const byte EMPTY = 0;
            public const byte HUMAN_CHESS = 1;
            public const byte PROGRAM_CHESS = 2;

            public short[,] chess = new short[row, column];

            public Position()
            {
                for (int i = 0; i < row; i++)
                    for (int j = 0; j < column; j++)
                        chess[i, j] = EMPTY;
            }
        }

        private void btn_Human_Click(object sender, RoutedEventArgs e)
        {
            board = new Position();
            if (txbSearchDepth.Text != "") maxDepth = Convert.ToInt32(txbSearchDepth.Text);
            player = HUMAN;
            canClick = true;
            DrawChessBoard();
        }

        private void btn_Program_First(object sender, RoutedEventArgs e)
        {
            board = new Position();
            if (txbSearchDepth.Text != "")
            {
                try { maxDepth = Convert.ToInt32(txbSearchDepth.Text); }
                catch (Exception) { }
            }
            player = PROGRAM;
            canClick = false;
            programTurn();
            DrawChessBoard();
            canClick = true;
            player = HUMAN;
        }
    }
}



你可能感兴趣的:(c#,AI)