Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A C# implementation of Reversi (Othello) Game for PocketPC and Windows

, 4 Aug 2004
A C# implementation of Reversi (Othello) Game for PocketPC and Windows.
pocketreversi_demo.zip
gma.Reversi.dll
gma.Windows.Reversi.exe
pocketreversi_setup.zip
install.ini
setup.exe
gma.ARMV4.CAB
pocketreversi_src.zip
gma.Windows.Reversi
gma.Windows.Reversi.csproj.user
Images
0.gif
1.gif
2.gif
3.gif
4.gif
5.gif
Reversi.ico
gma.Mobile.Reversi
gma.Mobile.Reversi.csdproj
gma.Mobile.Reversi.csdproj.user
Images
0.gif
1.gif
2.gif
3.gif
4.gif
5.gif
Reversi.ico
gma.Reversi
gma.Reversi.csproj.user
using System;
using System.Collections;	
using System.Collections.Specialized;
using System.Windows.Forms;

namespace gma.Reversi 
{
	public delegate void OnLogEvent (string msg);
	public delegate void OnProgressEvent (int Percent);

    public class VirtualPlayer : Player
    {

        public VirtualPlayer(BoardComplex aBoard):base(aBoard)
        {
        }

        public event OnLogEvent OnLog;
		public event OnProgressEvent OnProgress;

		protected override void _board_OnMoveTransferred(int aNextPlayer, int anAvailableMoveCount)
		{
			if (aNextPlayer != PlayerColor || anAvailableMoveCount == 0) return;
			Point theNextMove = GetNextMove();
			if (theNextMove.Equals(gma.Reversi.Board.NOMOVE)) return;
			_board.Play(theNextMove, PlayerColor, false);
		}

        public Point GetNextMove()
        {
            return MiniMaxAB(_board);
        }

        public int MAX_DEPTH = 3;
		protected virtual Point MiniMaxAB(BoardComplex aBoard)
		{
			IList Points_list = aBoard.GetAvailableMoves(PlayerColor);
			return MiniMaxAB(aBoard, Points_list);
		}

        protected Point MiniMaxAB(BoardComplex aBoard, IList Points_list)
		{
			if (Points_list.Count > 0)
			{
				int currentScore;
				Point bestMove = gma.Reversi.Board.NOMOVE;
				int bestMoveScore= int.MinValue;
				Point worstMove = gma.Reversi.Board.NOMOVE;
				int worstMoveScore= int.MaxValue;
				Point aPoint = gma.Reversi.Board.NOMOVE;
				
				int progressCounter=0;
				if (OnProgress!=null) OnProgress(0);
				foreach (Point aMove in Points_list)
				{
					Application.DoEvents();
					Board new_board = aBoard.Clone();
					new_board.Play(aMove, aBoard.CurrentPlayer,false);
					currentScore = MiniMaxAB(new_board, 0, int.MinValue, int.MaxValue);

					if (OnLog!=null) OnLog(String.Format("X={0} Y={1}  Score={2}", aMove.X, aMove.Y,  currentScore));
					if (currentScore > bestMoveScore)
					{
						bestMove = aMove;
						bestMoveScore = currentScore;
					}
					if (currentScore < worstMoveScore)
					{
						worstMove = aMove;
						worstMoveScore = currentScore;
					}
					progressCounter++;
					if (OnProgress!=null) OnProgress( progressCounter * 100 /Points_list.Count );
				}
				if (OnProgress!=null) OnProgress(0);

				if (aBoard.CurrentPlayer == PlayerColor)
				{
					if (OnLog!=null) OnLog(String.Format("Best X={0} Y={1}  Score={2}", bestMove.X, bestMove.Y,  bestMoveScore));
					return bestMove;
				}
				else
				{
					if (OnLog!=null) OnLog(String.Format("Worst X={0} Y={1}  Score={2}", worstMove.X, worstMove.Y,  worstMoveScore));
					return worstMove;
				}
			}
			else
				return gma.Reversi.Board.NOMOVE;
		}

		protected int MiniMaxAB(Board aBoard, int depth, int Alpha, int Beta)
		{
			//if N is a leaf because maximal depth was reached then
			//return the estimated score of this leaf
			if (depth == MAX_DEPTH) 
				return Score(aBoard);

			//if N is a leaf because no more Points left then
			//return the estimated score of this leaf
			IList Points_list = aBoard.GetAvailableMoves(aBoard.CurrentPlayer);
			if (Points_list.Count == 0)
				return Score(aBoard);

			//	Set Alpha value of N to -infinity and 
			//  Beta value of N to +infinity;
			int thisNodeAlpha= int.MinValue;
			int thisNodeBeta = int.MaxValue; 
			Point aPointToTry= new Point();

			// if N is a Max node then
			bool IsMaxNode = (aBoard.CurrentPlayer == PlayerColor);
			if (IsMaxNode)
			{
				foreach (Point aCurrentPoint in Points_list) //For each successor Ni of N loop
				{
					Board new_board = aBoard.Clone();
					new_board.Play(aCurrentPoint, aBoard.CurrentPlayer,false);
					int val=MiniMaxAB(new_board, depth + 1, Math.Max(Alpha, thisNodeAlpha), Beta); //Let Val be MINIMAX-AB(Ni, Max{A,Alpha value of N}, B);
					thisNodeAlpha = Math.Max( thisNodeAlpha, val);// Set Alpha value of N to Max{Alpha value of N, Val};
					if (thisNodeAlpha>=Beta)  
					{
						//if (OnLog!=null) OnLog("Break");
						break; //when  Alpha value of N >= B then 
					}
				}
				return thisNodeAlpha;
			}
			else // if N is a Min node then
			{
				foreach (Point aCurrentPoint in Points_list) //For each successor Ni of N loop
				{
					Board new_board = aBoard.Clone();
					new_board.Play(aCurrentPoint, aBoard.CurrentPlayer,false);
					int val=MiniMaxAB(new_board, depth + 1, Alpha, Math.Min(Beta, thisNodeBeta)); //Let Val be MINIMAX-AB(Ni, A, Min{B,Beta of N});
					thisNodeBeta = Math.Min( thisNodeBeta, val);// Set Beta value of N to Min{Beta value of N, Val};
					if (Alpha>=thisNodeBeta)
					{
						//if (OnLog!=null) OnLog("Break");
						break; //     When A >= Beta value of N then 
					}
				}
				return thisNodeBeta;
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

George Mamaladze
Software Developer
Germany Germany
Tweeter: @gmamaladze
Google+: gmamaladze
Blog: gmamaladze.wordpress.com
Follow on   Twitter

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 5 Aug 2004
Article Copyright 2004 by George Mamaladze
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid