Home→Forums→MonoBrick EV3 Firmware→Tic Tac Toe Bot→Reply To: Tic Tac Toe Bot
May 14, 2014 at 14:05
#4338

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 10 years, 10 months ago by
Orlando_2k.
Follow