Reply To: Tic Tac Toe Bot

HomeForumsMonoBrick EV3 FirmwareTic Tac Toe BotReply To: Tic Tac Toe Bot

#4338
Author Image
Orlando_2k
Participant

ok, so the link to the pdf should be:

http://cache.lego.com/r/www/r/mindstorms/community/services/downloads/bc129b2f-4a1b-431e-bf36-1cb922d94e73/buildinginstruction.pdf

now the code:
(the code might be ugly and inefficient, it’s just like it came to my mind)


using System;
using System.Threading;
using MonoBrickFirmware;
using MonoBrickFirmware.UserInput;
using MonoBrickFirmware.Display;
using MonoBrickFirmware.Sensors;
using MonoBrickFirmware.Movement;

namespace TTT
{
	class MainClass
	{
		//save all fields in an array
		//1 -> bot / 2 -> Player / 0 -> empty
		static byte[] array = new byte[9];
		//show some info on the LCD
		static void draw (string msg)
		{
			LcdConsole.Clear ();
			LcdConsole.WriteLine ("Bot: 1");
			LcdConsole.WriteLine ("Player: 2");
			LcdConsole.WriteLine ("  ");
			LcdConsole.WriteLine ("   " + array [1] + " | " + array [2] + " | " + array [3]);
			LcdConsole.WriteLine ("  ---+---+---");
			LcdConsole.WriteLine ("   " + array [8] + " | " + array [0] + " | " + array [4]);
			LcdConsole.WriteLine ("  ---+---+---");
			LcdConsole.WriteLine ("   " + array [7] + " | " + array [6] + " | " + array [5]);
			LcdConsole.WriteLine ("");
			LcdConsole.WriteLine ("Status:");
			LcdConsole.WriteLine (msg);
		}
		//test (player == 1) winning moves and (player == 2) blocking moves
		static int check (int player)
		{
			if (array [0] == player) {
				if (array [2] == player && array [6] == 0)
					return 6;
				if (array [6] == player && array [2] == 0)
					return 2;
				if (array [4] == player && array [8] == 0)
					return 8;
				if (array [8] == player && array [4] == 0)
					return 4;
			}

			if (array [1] == player && array [2] == player && array [3] == 0)
				return 3;
			if (array [2] == player && array [3] == player && array [1] == 0)
				return 1;
			if (array [1] == player && array [3] == player && array [2] == 0)
				return 2;

			if (array [3] == player && array [4] == player && array [5] == 0)
				return 5;
			if (array [5] == player && array [4] == player && array [3] == 0)
				return 3;
			if (array [3] == player && array [5] == player && array [4] == 0)
				return 4;

			if (array [5] == player && array [6] == player && array [7] == 0)
				return 7;
			if (array [7] == player && array [6] == player && array [5] == 0)
				return 5;
			if (array [7] == player && array [5] == player && array [6] == 0)
				return 6;

			if (array [7] == player && array [8] == player && array [1] == 0)
				return 1;
			if (array [1] == player && array [8] == player && array [7] == 0)
				return 7;
			if (array [1] == player && array [7] == player && array [8] == 0)
				return 8;
			return -1;
		}
		//get a free corner
		static int freeCorner ()
		{
			if (array [1] == 0)
				return 1;
			if (array [3] == 0)
				return 3;
			if (array [5] == 0)
				return 5;
			if (array [7] == 0)
				return 7;
			return -1;
		}
		//get a free edge
		static int freeEdge ()
		{
			if (array [2] == 0)
				return 2;
			if (array [4] == 0)
				return 4;
			if (array [6] == 0)
				return 6;
			if (array [8] == 0)
				return 8;
			return -1;
		}
		//test if the last move finished the game
		static bool finished ()
		{

			return(
			(array [0] == array [2] && array [2] == array [6] && array [0] != 0) ||
			(array [0] == array [4] && array [4] == array [8] && array [0] != 0) ||
			(array [1] == array [2] && array [2] == array [3] && array [1] != 0) ||
			(array [3] == array [4] && array [4] == array [5] && array [3] != 0) ||
			(array [5] == array [6] && array [6] == array [7] && array [5] != 0) ||
			(array [7] == array [8] && array [8] == array [1] && array [7] != 0));

		}
		//make a move
		static void put (int field)
		{
			draw ("Bots Turn");

			array [field] = 1;
			mArm.MoveTo (50, 110, true, true);
			mGrip.On (-20);
			System.Threading.Thread.Sleep (400);
			mGrip.Off ();
			mArm.MoveTo (70, 0, true, true);
			if (field == 0) {
				mTurn.MoveTo (70, 670, true, true);
			} else {
				mField.MoveTo (100, scanPos + (field * 315), true, true);
				if (field > 3)
					scanPos += (360 * 7);
				if (field % 2 != 0) {
					mTurn.MoveTo (70, 570, true, true);
				} else {
					mTurn.MoveTo (70, 580, true, true);
				}
			}
			mArm.MoveTo (50, 20, true, true);
			mGrip.On (20);
			System.Threading.Thread.Sleep (300);
			mGrip.Off ();
			mArm.MoveTo (70, 0, true, true);
			mTurn.MoveTo (70, 0, true, true);
			mField.MoveTo (100, scanPos, true, true);
		}

		//variable to save fields rotation
		static int scanPos = 0;
		//search for the players move
		static void scan ()
		{
			draw ("Bot is scanning...");

			bool test = false;
			int i;
			while (test == false) {
				for (i=1; i<9; i++) {
					if (array [i] == 0) {
						mField.MoveTo (100, scanPos + (i * 315), true, true);
						if (cSensor.Read () > 0) {
							array [i] = 2;
							test = true;
							break;
						}
					}
				}
				if (i > 3)
					scanPos += (360 * 7);
				mField.MoveTo (100, scanPos, true, true);

				//if the new move is not detected it has to be the center field
				if (test == false && array [0] == 0) {
					array [0] = 2;
					break;
				}
			}
		}

		//wait for the player to make his move
		static void waitForPlayer ()
		{
			draw ("Players Turn");

			while (irSensor.Read() <= 15) {
			}
			while (irSensor.Read() > 15) {
			}
			System.Threading.Thread.Sleep (3000);
		}

		//End programm when Esc is hit
		static void registerAbortEvent ()
		{
			ButtonEvents buts = new ButtonEvents ();
			buts.EscapePressed += () =>
			{
				Environment.Exit (0);
			};
		}

		static Motor mField = new Motor (MotorPort.OutC);
		static Motor mArm = new Motor (MotorPort.OutB);
		static Motor mGrip = new Motor (MotorPort.OutD);
		static Motor mTurn = new Motor (MotorPort.OutA);
		static ColorSensor cSensor = new ColorSensor (SensorPort.In1);
		static IRSensor irSensor = new IRSensor (SensorPort.In2, IRMode.Proximity);

		public static void Main (string[] args)
		{
			mField.ResetTacho ();
			mArm.ResetTacho ();
			mTurn.ResetTacho ();
			registerAbortEvent ();
			waitForPlayer ();  //remove these lines to make the bot start
			scan ();           //remove these lines to make the bot start

//first move is hardcoded
			if (array [0] == 2) {
				put (1);
			} else {
				put (0);
			}

			int nextMove;
			while (true) {
				waitForPlayer ();
				scan ();

				if (finished ()) {
					draw ("PLAYER WINS!");
					break;
				}
				nextMove = check (1);
				if (nextMove == -1)
					nextMove = check (2);
				if ((array [1] == 2 && array [5] == 2 && array [0] == 1) || (array [7] == 2 && array [3] == 2 && array [0] == 1)) {  //change the strategy to avoid a trap situation
					if (nextMove == -1)
						nextMove = freeEdge ();
					if (nextMove == -1)
						nextMove = freeCorner ();
				} else {
					if (nextMove == -1)
						nextMove = freeCorner ();
					if (nextMove == -1)
						nextMove = freeEdge ();
				}
				if (nextMove == -1) {
					draw ("GAME OVER");
					break;
				}

				put (nextMove);
				if (finished ()) {
					draw ("BOT WINS!");
					break;
				}

			}
			System.Threading.Thread.Sleep (3 * 60 * 1000);
		}
	}
}
  • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
Posted in

Make a donation