ROBOTC.net forums
http://robotc.net/forums/

RCX TTT Player
http://robotc.net/forums/viewtopic.php?f=15&t=5502
Page 3 of 4

Author:  Coder A [ Sat Apr 27, 2013 4:08 pm ]
Post subject:  Re: RCX TTT Player

How good is the code? Is it unbeatable but imperfect (i.e. it doesn't win every time it can) or is it still beatable?

Author:  NeXT-Generation [ Sat Apr 27, 2013 4:44 pm ]
Post subject:  Re: RCX TTT Player

Um yeah totally beatable. Plus there are several glitches such as: if you win it still keeps playing.

Author:  Coder A [ Sun Apr 28, 2013 12:39 pm ]
Post subject:  Re: RCX TTT Player

:) That's just like some of my friends! They are totally beatable AND they keep playing after I win!

Author:  NeXT-Generation [ Thu May 02, 2013 3:54 pm ]
Post subject:  Re: RCX TTT Player

I rewrote the code. I also got rid of the Arduino circuit in favor of an autovalve. Current code here:

Code:
#pragma config(Sensor, S1, LhtLmt, sensorReflection)
#pragma config(Sensor, S2, xPos, sensorTouch)
#pragma config(Sensor, S3, yPos, sensorTouch)
#pragma config(Motor, motorA, PneumSwch, tmotorNormal, openLoop)
#pragma config(Motor, motorB, xAxis, tmotorNormal, openLoop)
#pragma config(Motor, motorC, yAxis, tmotorNormal, openLoop)

void ClawCntrl(char Action);
void MoveHeadToLoc(byte xCoord, byte yCoord);

byte OppThrs;
byte xHeadPos;
byte yHeadPos;
byte xCoordToMoveTo;
byte yCoordToMoveTo;

bool GameFinished = false;
bool MoveFound = false;

byte Board[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
char WhoWon;

byte PieceCount = 0;

task main()
{
   motor[xAxis] = -100;
   while(SensorValue(LhtLmt) != 100);
   motor[xAxis] = 100;
   while(SensorValue(xPos) == 0);
   motor[xAxis] = 0;

   motor[yAxis] = -50;
   while(SensorValue(LhtLmt) != 100);
   motor[yAxis] = 50;
   while(SensorValue(yPos) == 0);
   motor[yAxis] = 0;

   ClawCntrl('C');
   ClawCntrl('O');

   xHeadPos = 0;
   yHeadPos = 0;

   OppThrs = SensorValue(LhtLmt) - 6;

  while(GameFinished == false)
   {
     PlayImmediateTone(3000, 75);

     while(SensorValue(LhtLmt) != 100);

     for(byte y = 0; y < 3; y++)
     {
       for(byte x = 0; x < 3; x++)
       {
         MoveHeadToLoc(x + 2, y);
         if(SensorValue(LhtLmt) > OppThrs)
         {
           Board[x + y * 3] = 1;
           PlaySound(soundDownwardTones);
         }
         else if(Board[x + y * 3] == 2) PlaySound(soundUpwardTones);
         else PlaySound(soundException);
       }
     }

     if((Board[0 + 0 * 3] == 1 && Board[0 + 1 * 3] == 1 && Board[0 + 2 * 3] == 1) ||
     (Board[1 + 0 * 3] == 1 && Board[1 + 1 * 3] == 1 && Board[1 + 2 * 3] == 1) ||
     (Board[2 + 0 * 3] == 1 && Board[2 + 1 * 3] == 1 && Board[2 + 2 * 3] == 1) ||
     (Board[0 + 0 * 3] == 1 && Board[1 + 0 * 3] == 1 && Board[2 + 0 * 3] == 1) ||
     (Board[0 + 1 * 3] == 1 && Board[1 + 1 * 3] == 1 && Board[2 + 1 * 3] == 1) ||
     (Board[0 + 2 * 3] == 1 && Board[1 + 2 * 3] == 1 && Board[2 + 2 * 3] == 1) ||
     (Board[0 + 0 * 3] == 1 && Board[1 + 1 * 3] == 1 && Board[2 + 2 * 3] == 1) ||
     (Board[2 + 0 * 3] == 1 && Board[1 + 1 * 3] == 1 && Board[0 + 2 * 3] == 1))
     {
       WhoWon = 'O';
       GameFinished = true;
     }

     else
     {
       MoveFound = false;
       byte i = 2;

       while(i >= 1 && MoveFound == false)
       {
         if(((Board[0 + 2 * 3] == i && Board[0 + 1 * 3] == i) ||
         (Board[0 + 2 * 3] == i&& Board[0 + 1 * 3] == i) ||
         (Board[0 + 2 * 3] == i&& Board[0 + 1 * 3] == i)) && Board[0 + 0 * 3] == 0)
         {
           xCoordToMoveTo = 0;
           yCoordToMoveTo = 0;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[2 + 0 * 3] == i) ||
         (Board[1 + 1 * 3] == i&& Board[1 + 2 * 3] == i)) && Board[1 + 0 * 3] == 0)
         {
           xCoordToMoveTo = 1;
           yCoordToMoveTo = 0;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[1 + 0 * 3] == i) ||
         (Board[0 + 2 * 3] == i&& Board[1 + 1 * 3] == i) ||
         (Board[2 + 2 * 3] == i&& Board[2 + 1 * 3] == i)) && Board[2 + 0 * 3] == 0)
         {
           xCoordToMoveTo = 2;
           yCoordToMoveTo = 0;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[0 + 2 * 3] == i) ||
         (Board[1 + 1 * 3] == i&& Board[2 + 1 * 3] == i)) && Board[0 + 1 * 3] == 0)
         {
           xCoordToMoveTo = 0;
           yCoordToMoveTo = 1;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[2 + 2 * 3] == i) ||
         (Board[0 + 2 * 3] == i&& Board[2 + 0 * 3] == i) ||
         (Board[0 + 1 * 3] == i&& Board[2 + 1 * 3] == i) ||
         (Board[1 + 0 * 3] == i&& Board[1 + 2 * 3] == i)) && Board[1 + 1 * 3] == 0)
         {
           xCoordToMoveTo = 1;
           yCoordToMoveTo = 1;
           MoveFound = true;
         }
         else if(((Board[2 + 0 * 3] == i && Board[2 + 2 * 3] == i) ||
         (Board[0 + 1 * 3] == i&& Board[1 + 1 * 3] == i)) && Board[2 + 1 * 3] == 0)
         {
           xCoordToMoveTo = 2;
           yCoordToMoveTo = 1;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[0 + 1 * 3] == i) ||
         (Board[2 + 0 * 3] == i&& Board[1 + 1 * 3] == i) ||
         (Board[1 + 2 * 3] == i&& Board[2 + 2 * 3] == i)) && Board[0 + 2 * 3] == 0)
         {
           xCoordToMoveTo = 0;
           yCoordToMoveTo = 2;
           MoveFound = true;
         }
         else if(((Board[0 + 2 * 3] == i && Board[2 + 2 * 3] == i) ||
         (Board[1 + 0 * 3] == i&& Board[1 + 1 * 3] == i)) && Board[1 + 2 * 3] == 0)
         {
           xCoordToMoveTo = 1;
           yCoordToMoveTo = 2;
           MoveFound = true;
         }
         else if(((Board[0 + 0 * 3] == i && Board[1 + 1 * 3] == i) ||
         (Board[0 + 2 * 3] == i&& Board[1 + 2 * 3] == i) ||
         (Board[2 + 0 * 3] == i&& Board[2 + 1 * 3] == i)) && Board[2 + 2 * 3] == 0)
         {
           xCoordToMoveTo = 2;
           yCoordToMoveTo = 2;
           MoveFound = true;
         }

         i--;
       }

       if(MoveFound == true)
       {
         MoveHeadToLoc(4, 1);
         while(SensorValue(LhtLmt) != 100);
         MoveHeadToLoc(4, 2);
         ClawCntrl('C');
         MoveHeadToLoc(xCoordToMoveTo, yCoordToMoveTo);
         ClawCntrl('O');
         MoveHeadToLoc(0, 0);
         Board[xCoordToMoveTo + yCoordToMoveTo * 3] = 2;

         if((Board[0 + 0 * 3] == 2 && Board[0 + 1 * 3] == 2 && Board[0 + 2 * 3] == 2) ||
         (Board[1 + 0 * 3] == 2 && Board[1 + 1 * 3] == 2 && Board[1 + 2 * 3] == 2) ||
         (Board[2 + 0 * 3] == 2 && Board[2 + 1 * 3] == 2 && Board[2 + 2 * 3] == 2) ||
         (Board[0 + 0 * 3] == 2 && Board[1 + 0 * 3] == 2 && Board[2 + 0 * 3] == 2) ||
         (Board[0 + 1 * 3] == 2 && Board[1 + 1 * 3] == 2 && Board[2 + 1 * 3] == 2) ||
         (Board[0 + 2 * 3] == 2 && Board[1 + 2 * 3] == 2 && Board[2 + 2 * 3] == 2) ||
         (Board[0 + 0 * 3] == 2 && Board[1 + 1 * 3] == 2 && Board[2 + 2 * 3] == 2) ||
         (Board[2 + 0 * 3] == 2 && Board[1 + 1 * 3] == 2 && Board[0 + 2 * 3] == 2))
         {
           WhoWon = 'M';
           GameFinished = true;
         }
       }
       else
       {
         if((Board[0 + 0 * 3] == 2 || Board[2 + 2 * 3] == 2 ||
         Board[0 + 2 * 3] == 2 || Board[2 + 0 * 3] == 2) &&
         Board[1 + 1 * 3] == 0)
         {
           xCoordToMoveTo = 1;
           yCoordToMoveTo = 1;
           MoveFound = true;
         }
         else if(Board[0 + 0 * 3] == 0)
         {
           xCoordToMoveTo = 0;
           yCoordToMoveTo = 0;
           MoveFound = true;
        }
         else if(Board[2 + 2 * 3] == 0)
         {
           xCoordToMoveTo = 2;
           yCoordToMoveTo = 0;
           MoveFound = true;
         }
         else if(Board[0 + 2 * 3] == 0)
         {
           xCoordToMoveTo = 0;
           yCoordToMoveTo = 2;
           MoveFound = true;
         }
         else if(Board[2 + 0 * 3] == 0)
         {
           xCoordToMoveTo = 2;
           yCoordToMoveTo = 2;
           MoveFound = true;
         }

         if(MoveFound == true)
         {
           MoveHeadToLoc(4, 1);
           while(SensorValue(LhtLmt) != 100);
           MoveHeadToLoc(4, 2);
           ClawCntrl('C');
           MoveHeadToLoc(xCoordToMoveTo, yCoordToMoveTo);
           ClawCntrl('O');
           MoveHeadToLoc(0, 0);
           Board[xCoordToMoveTo + yCoordToMoveTo * 3] = 2;
         }
         else
         {
           WhoWon = 'D';
           GameFinished = true;
         }
       }
     }
   }

   MoveHeadToLoc(0, 0);
}

void ClawCntrl(char Action)
{
   if(Action == 'C')
   {
      motor[PneumSwch] = 100;
      wait1Msec(3500);
      motor[PneumSwch] = 0;
   }
   else if(Action == 'O')
   {
      motor[PneumSwch] = -100;
      wait1Msec(3500);
      motor[PneumSwch] = 0;
   }
}

void MoveHeadToLoc(byte xCoord, byte yCoord)
{
  char Dir;

   if(xCoord > xHeadPos) Dir = 'R';
   else if(xCoord < xHeadPos) Dir = 'L';

   if(Dir == 'R')
   {
      for(byte MveCnt = xHeadPos; MveCnt < xCoord; MveCnt++)
      {
         motor[xAxis] = 100;
         while(SensorValue(xPos) == 1);
         while(SensorValue(xPos) == 0);
         while(SensorValue(xPos) == 1);
         motor[xAxis] = -100;
         while(SensorValue(xPos) == 0);
         motor[xAxis] = 0;

         xHeadPos++;
      }
   }
   else if(Dir == 'L')
   {
      for(byte MveCnt = xHeadPos; MveCnt > xCoord; MveCnt--)
      {
         motor[xAxis] = -100;
         while(SensorValue(xPos) == 1);
         while(SensorValue(xPos) == 0);
         motor[xAxis] = 0;

         xHeadPos--;
      }
   }

   if(yCoord > yHeadPos) Dir = 'U';
   else if(yCoord < yHeadPos) Dir = 'B';

   if(Dir == 'U')
   {
      for(byte MveCnt = yHeadPos; MveCnt < yCoord; MveCnt++)
      {
         motor[yAxis] = 50;
         while(SensorValue(yPos) == 1);
         while(SensorValue(yPos) == 0);
         motor[yAxis] = 0;

         yHeadPos++;
      }
   }
   else if(Dir == 'B')
   {
      for(byte MveCnt = yHeadPos; MveCnt > yCoord; MveCnt--)
      {
         motor[yAxis] = -50;
         while(SensorValue(yPos) == 1);
         while(SensorValue(yPos) == 0);
         while(SensorValue(yPos) == 1);
         motor[yAxis] = 50;
         while(SensorValue(yPos) == 0);
         motor[yAxis] = 0;

         yHeadPos--;
      }
   }
}


It's some 200 lines shorter than my original code and performs better. I'm testing it as the human player in a supposedly unbeatable TTT program I found. :lol:

Author:  Coder A [ Thu May 02, 2013 4:34 pm ]
Post subject:  Re: RCX TTT Player

Just a question: Have you considered rewriting the board as a 2-dimensional array? Of course with the right code 1-D's are just as good as 2-D's.

Author:  NeXT-Generation [ Thu May 02, 2013 4:39 pm ]
Post subject:  Re: RCX TTT Player

RCX no support 2D array. :(

That's why I have a 9-cell array and address it like so:
Code:
Board[x + y * 3] = 1;

Ends up working just like a 2D array, with just that little bit of extra maths when addressing it.

Author:  Coder A [ Thu May 02, 2013 4:42 pm ]
Post subject:  Re: RCX TTT Player

Yeah. I once wrote the bones of a maze solving robot w/ a 1D array, then realized that robotc supported 2D's, so I rewrote all 800+ lines...... tiring.

Author:  NeXT-Generation [ Thu May 02, 2013 4:47 pm ]
Post subject:  Re: RCX TTT Player

Yeah... :|

800+ for a maze solving robot sounds a bit excessive though. I did one that solved a physical maze, like it actually followed the lines that the maze was made out of, and it was less than 400 lines including victory music. :P

Author:  Coder A [ Thu May 02, 2013 5:51 pm ]
Post subject:  Re: RCX TTT Player

Well actually, over half was the extremely user-friendly interface. That might be why it was long. You could select start, finish, mode(there, there & back, or find exit), direction robot originally faces, and save or erase the known data of the walls. It was nice.

Author:  NeXT-Generation [ Thu May 02, 2013 6:10 pm ]
Post subject:  Re: RCX TTT Player

Well there's your problem! :lol: Although mine didn't do a wall maze, it was a maze made out of tape on floor tiles.

Author:  Coder A [ Fri May 03, 2013 11:41 am ]
Post subject:  Re: RCX TTT Player

So when you say it performs better, how much better? Can you still beat it?

Author:  NeXT-Generation [ Fri May 03, 2013 11:48 am ]
Post subject:  Re: RCX TTT Player

Yeah I can still beat it. I improved it a bit today, but still trying to find the level of unbeatableness that I've seen in other things. It's less susceptible to forks now, but there are still a few bugs.

Author:  NeXT-Generation [ Mon May 06, 2013 11:54 am ]
Post subject:  Re: RCX TTT Player

I found a seemingly unbeatable TTT strategy in an old book of mine. I'm gonna try to implement it and see if the performance improves. Work is gonna halt on this for a bit as I'm working on another flexpicker. :mrgreen:

Author:  mightor [ Mon May 06, 2013 3:04 pm ]
Post subject:  Re: RCX TTT Player

Can you use the flex picker to pick and place the balls for the TTT?

= Xander

Author:  NeXT-Generation [ Mon May 06, 2013 3:31 pm ]
Post subject:  Re: RCX TTT Player

Probably. Although that kinda defeats the purpose of doing it with just an RCX.

CELEBRATION!! 500 posts!! :mrgreen: :mrgreen: :mrgreen:

Page 3 of 4 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/