LOL! I had to do this 10 years ago in C. In this case, C is almost identical to java. Let me know if you want the other files referenced:
Code: Select all
/*----------------------------------------------------------------------+
| Title: mazeWalker.c |
| Reinforcement learning used to navigate through a maze |
| |
| Authors: Mark Hokanson |
| Matt Waxman |
| Dan Prantl |
| Clark University |
| Worcester, MA 01610-1477 |
| U.S.A. |
| |
| Date: April 1998. |
| Time Stamp: <98/04/24 19:38:48 waxman> |
+----------------------------------------------------------------------*/
#include <stdio.h>
#include "RoboSim.h"
#include "SimDisp.h"
#include <time.h>
#include <unistd.h>
#include <math.h>
#define WALL_LENGTH 1000
#define PIXEL_SIZE 100
#define ROBOT_SIZE 80
#define DISPLAY_CORRECTION 80
#define SUCCESS 1
#define FAIL 0
#define UP 2
#define DOWN 0
#define RIGHT 1
#define LEFT 3
#define GAMMA 0.9
#define GOAL_X 10 /* Goal State Coords */
#define GOAL_Y 7
#define WALL -1
#define RANDOM_WALKS 25
#define GOAL_AMOUNT 1000
#define WALL_WIDTH 0.3*PIXEL_SIZE
/* Function prototypes */
int moveUp(void);
int moveDown(void);
int moveLeft(void);
int moveRight(void);
void randomMove(void);
void selectiveMove(void);
void q_function(void);
void printGrid(void);
void createWalls(World *w);
void add_wall(World *w, int from_x, int from_y, int to_x, int to_y);
void test(World *w);
/* Global Variables */
Point p;
SimDisp *sd;
World *w;
Robot *r;
int x,y;
int grid[WALL_LENGTH/PIXEL_SIZE][WALL_LENGTH/PIXEL_SIZE];
void
main(void)
{
int i,j, coordx=1, coordy=1;
w = makeWorld(WALL_LENGTH,WALL_LENGTH);
sd = makeSimDisp(w, 1, "black", "purple", "red");
r = makeRobot(ROBOT_SIZE,ROBOT_SIZE);
p.x = (PIXEL_SIZE*0.1); p.y = (PIXEL_SIZE*0.1)+DISPLAY_CORRECTION;
x=0; y=0;
addRobot(w, r, p, 0);
drawWorld(sd);
/* initialize grid to all 0's */
for(i=0;i<WALL_LENGTH/PIXEL_SIZE;i++)
{
for(j=0;j<WALL_LENGTH/PIXEL_SIZE;j++)
grid[i][j]=0;
}
/* set goal state */
grid[GOAL_X-1][GOAL_Y-1]=GOAL_AMOUNT;
createWalls(w);
drawWorld(sd);
q_function();
/* move back to start position (top left) */
p.x = (PIXEL_SIZE*0.1); p.y = (PIXEL_SIZE*0.1)+DISPLAY_CORRECTION;
x=0; y=0;
drawWorld(sd);
addRobot(w, r, p, 0);
drawWorld(sd);
while(x!=(GOAL_X-1) || y!=(GOAL_Y-1))
{
selectiveMove();
drawWorld(sd);
sleep(1);
}
}
int
moveUp()
{
p.y = p.y-PIXEL_SIZE;
if(p.y<0 || grid[x][y-1]==WALL)
{
p.y=p.y+PIXEL_SIZE;
return FAIL;
}
else
{
addRobot(w, r, p, 0);
y--;
return SUCCESS;
}
}
int
moveDown()
{
p.y = p.y+PIXEL_SIZE;
if(p.y>WALL_LENGTH || grid[x][y+1]==WALL)
{
p.y = p.y-PIXEL_SIZE;
return FAIL;
}
else
{
addRobot(w, r, p, 0);
y++;
return SUCCESS;
}
}
int
moveLeft()
{
p.x = p.x-PIXEL_SIZE;
if(p.x<0 || grid[x-1][y]==WALL)
{
p.x = p.x+PIXEL_SIZE;
return FAIL;
}
else
{
addRobot(w, r, p, 0);
x--;
return SUCCESS;
}
}
int
moveRight()
{
p.x = p.x+PIXEL_SIZE;
if(p.x>WALL_LENGTH || grid[x+1][y]==WALL)
{
p.x = p.x-PIXEL_SIZE;
return FAIL;
}
else
{
addRobot(w, r, p, 0);
x++;
return SUCCESS;
}
}
void
randomMove(void)
{
int i,temp;
for(i=0;i<1;i++)
{
temp=rand()%4;
switch (temp)
{
case DOWN:
if(!moveDown()) i--;
break;
case RIGHT:
if(!moveRight()) i--;
break;
case UP:
if(!moveUp()) i--;
break;
case LEFT:
if(!moveLeft()) i--;
break;
}
}
}
void
selectiveMove(void)
{
int temp_value,move;
/* NOTE: should be an && but for some reason the compiler thinks of them opposite */
temp_value=0;
if((y-1)>0)
if(temp_value<grid[x][y-1])
{
temp_value=grid[x][y-1];
move=UP;
}
if((x+1)<WALL_LENGTH/PIXEL_SIZE)
if(temp_value<grid[x+1][y])
{
temp_value=grid[x+1][y];
move=RIGHT;
}
if((y+1)<WALL_LENGTH/PIXEL_SIZE)
if(temp_value<grid[x][y+1])
{
temp_value=grid[x][y+1];
move=DOWN;
}
if((x-1)>0)
if(temp_value<grid[x-1][y])
{
temp_value=grid[x-1][y];
move=LEFT;
}
if(temp_value==0)
randomMove();
else
{
switch (move)
{
case DOWN:
if(moveDown()) ;
break;
case RIGHT:
if(moveRight()) ;
break;
case UP:
if(moveUp()) ;
break;
case LEFT:
if(moveLeft()) ;
break;
}
}
}
void
q_function(void)
{
int temp_x,temp_y;
int walks=0, i=0;
while(walks<RANDOM_WALKS)
{
rewind(stderr);
temp_x=x; temp_y=y;
if(rand()%2==1) randomMove();
else selectiveMove();
/* if(i++%100==1)
drawWorld(sd); update display every 10 iterations */
if(grid[temp_x][temp_y]<(grid[x][y]*GAMMA))
grid[temp_x][temp_y]= GAMMA*grid[x][y];
if(x==GOAL_X-1 && y==GOAL_Y-1)
{
walks++;
p.x = (PIXEL_SIZE*0.1); p.y = (PIXEL_SIZE*0.1)+DISPLAY_CORRECTION;
x=0; y=0;
addRobot(w, r, p, 0);
drawWorld(sd);
}
}
printGrid();
}
void
printGrid(void)
{
int i,j;
for(i=0;i<WALL_LENGTH/PIXEL_SIZE;i++)
{
for(j=0;j<WALL_LENGTH/PIXEL_SIZE;j++)
fprintf(stderr,"%d ",grid[j][i]);
fprintf(stderr,"
");
}
}
/* set walls */
void
createWalls(World *w)
{
Point p1,p2;
int i;
grid[1][0]=WALL;
grid[1][1]=WALL;
grid[1][2]=WALL;
grid[3][2]=WALL;
grid[3][3]=WALL;
grid[4][3]=WALL;
grid[5][3]=WALL;
grid[5][2]=WALL;
grid[7][2]=WALL;
grid[8][2]=WALL;
grid[8][3]=WALL;
grid[8][4]=WALL;
grid[8][5]=WALL;
grid[7][5]=WALL;
grid[7][6]=WALL;
grid[7][7]=WALL;
grid[6][7]=WALL;
grid[5][7]=WALL;
grid[5][6]=WALL;
grid[5][5]=WALL;
grid[9][5]=WALL;
grid[9][7]=WALL;
grid[2][6]=WALL;
grid[2][7]=WALL;
grid[2][8]=WALL;
grid[2][9]=WALL;
grid[2][5]=WALL;
grid[2][4]=WALL;
grid[3][4]=WALL;
add_wall(w,120,0,120,280);
add_wall(w,320,220,320,420);
add_wall(w,220,420,380,420);
add_wall(w,520,220,520,320);
add_wall(w,320,320,580,320);
add_wall(w,720,220,820,220);
add_wall(w,820,220,820,520);
add_wall(w,720,520,1000,520);
add_wall(w,720,520,720,720);
add_wall(w,520,520,520,720);
add_wall(w,520,720,780,720);
add_wall(w,220,420,220,1000);
add_wall(w,920,720,1000,720);
/*
for(i=100;i<=900;i=i+100)
{
p1.x=i; p1.y=0;
p2.x=i; p2.y=1000;
addWall(w,p1,p2);
}
for(i=100;i<=900;i=i+100)
{
p1.x=0; p1.y=i;
p2.x=1000; p2.y=i;
addWall(w,p1,p2);
}*/
}
void
add_wall(World *w, int from_x, int from_y, int to_x, int to_y)
{
Point p1, p2;
int i;
p1.x=from_x; p1.y=from_y;
p2.x=to_x; p2.y=to_y;
addWall(w,p1,p2);
for(i=0;i<WALL_WIDTH;i++)
{
if(from_y==to_y)
{
p1.x=from_x; p1.y=from_y+i-1;
p2.x=to_x; p2.y=to_y+i-1;
addWall(w,p1,p2);
p1.x=from_x; p1.y=from_y+i+1;
p2.x=to_x; p2.y=to_y+1+i;
addWall(w,p1,p2);
from_y++;
to_y++;
}
else
{
p1.x=from_x+i-1; p1.y=from_y;
p2.x=to_x+i-1; p2.y=to_y;
addWall(w,p1,p2);
p1.x=from_x+i+1; p1.y=from_y;
p2.x=to_x+1+i; p2.y=to_y;
addWall(w,p1,p2);
from_x++;
to_x++;
}
}
}
void test(World *w)
{
Point p1,p2;
int i;
for(i=0;i==1000;i=i+100)
{
p1.x=i; p1.y=0;
p2.x=i; p2.y=1000;
addWall(w,p1,p2);
}
for(i=0;i==1000;i=i+100)
{
p1.x=0; p1.y=i;
p2.x=0; p2.y=i;
addWall(w,p1,p2);
}
}