Tic Tac Toe Bot

HomeForumsMonoBrick EV3 FirmwareTic Tac Toe Bot

This topic contains 10 replies, has 3 voices, and was last updated by Author Image Helmut Wunder 3 years, 3 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #4322
    Author Image
    Orlando_2k
    Participant

    Hi, this is Orlando_2k from the Lego Mindstorms community.
    Anders Posted something over there:
    http://www.us.lego.com/en-us/mindstorms/community/robot?projectid=a4584682-4581-435d-93df-e2f3d33a30f7

    “Hi I am one of the creators of the MonoBrick firmware. I would like use your robot to promote MonoBrick. If you are interested please visit our webpage and use the contact form to start talking… Anders”

    I tried to use the contact form but didn’t get an answer yet…
    Are you still interested?

    #4323
    Author Image
    Helmut Wunder
    Participant

    hea,
    this looks vera interesting – where can one download the Mono/C# source code ?

    #4324
    Author Image
    Anders Søborg
    Key Master

    Hi Orlando

    This looks very nice sure we are still interested. Please post some videos and some pictures… Then I will use it on the Firmware page. How does that sound?

    @Helmut
    The source can be found here

    Anders

    #4327
    Author Image
    Helmut Wunder
    Participant

    I meant the code for the tictactoe bot…

    #4328
    Author Image
    Orlando_2k
    Participant

    @Helmut Wunder: You can download a “BuildingInstruction.pdf” at the project page. The source code is at the end of that document. (If you want to copy paste it, I can repost the code here (the mindstorms community doesn’t allow all file types :-( ))

    @Anders Søborg: why didn’t the contact form work for me?
    You can use the images and videos from the projectpage. Let me know if you need anything else!
    can you please add a link to my profile page, so guests can check out my other robots?
    my profile page:

    http://www.us.lego.com/en-us/mindstorms/community/profile?builder=Orlando_2k

    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    #4329
    Author Image
    Orlando_2k
    Participant

    sorry, double post

    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    #4337
    Author Image
    Helmut Wunder
    Participant

    hey,
    yes, it would be very nice if you posted the code here, too, and maybe a link to the pdf additionally, I find the Lego site very confusing

    #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.
    #4340
    Author Image
    Helmut Wunder
    Participant

    thanks for sharing your project!
    Surely not only an amazing project but also a big help for people starting with mono to look and learn from your code! 8-)
    as some people in our German forum are just about starting with Mono I linked your project for people who might be interested:

    http://www.mindstormsforum.de/viewtopic.php?f=70&t=8272

    #4341
    Author Image
    Orlando_2k
    Participant

    awesome,
    I am from Germany, too.

    EDIT: Oh, and you’re an admin of http://www.mindstormsforum.de
    I will have to take a look at this forum :-D

    • This reply was modified 3 years, 3 months ago by Author Image Orlando_2k.
    #4343
    Author Image
    Helmut Wunder
    Participant

    you’re welcome to join us :)

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.

Posted in

Make a donation