Category : C Source Code
Archive   : TTT.ZIP
Filename : TTT.C

 
Output of file : TTT.C contained in archive : TTT.ZIP
/* This program simulates a constraint satisfaction
neural network for choosing tic-tac-toe moves as
described in Volume 2 of the PDP books. The
network is presented a description of the board
and chooses the best move subject to predefined
constraints.

It requires an EGA or CGA to display a Hinton diagram
of the element activation levels.

Author : Gary Andriotakis
Compiler : Microsoft Quick C
Date : 5 January 1989
*/
#include
#include
#include
#include
#define N 67
#define GAIN 0.1
#define SCALE 1.0/16.0
static float w[N][N], bias[N], a[N], e[N];
main()
{
int j,mark = -1,converged;
time_t t;
#ifdef DEBUG
initialize(a,w,bias);
#endif
#ifndef DEBUG
if(!_setvideomode(_ERESCOLOR))
{ printf("EGA required\n");
exit(0);
}
srand((int)time(&t));
drawboard();
do
{
putmarkers(&e[9],mark);
initialize();
boxes(a,N);
do
{ j = randint(N);
update(j);
boxes(a,j);
converged = ((j < 9) && (a[j] > 0.9));
} while(!converged && !kbhit());
if(converged)
mark = j;
else
mark = -1;
} while(converged || (kbhit() && getch() != 27));
_displaycursor(_GCURSORON);
_setvideomode(_DEFAULTMODE);
#endif
}

update(j)
int j;
{ int i;
float net;

net = 0.0;
for(i = 0; i < N; i++)
net += w[i][j]*a[i];
net += bias[j];
net *= GAIN;
net += e[j];
if(net > 0.0)
a[j] += net*(1.0 - a[j]);
else
a[j] += net*a[j];
}

initialize()
{ int i,j;
/* initialize to zero */
for(i = 0; i < N; i++)
{ a[i] = 0.0;
bias[i] = 0.0;
for(j = 0; j < N; j++)
w[i][j] = 0.0;
}

for(i = 0; i < 9; i++)
{ /* inhibit responses from occupied squares */
w[i+9][i] = -8.0;
w[i+18][i] = -8.0;
/* mutual inhibition to insure only one response */
for(j = 0; j < 9; j++)
w[i][j] = -2.;
/* self excitation to excourage self growth */
w[i][i] = 2.;
}
/* empty line detectors */
for(i = 0; i < 3; i++)
{ w[i+9][27] = -1.0;
w[i+18][27] = -1.0;
w[27][i] = 1.0;
w[i+12][28] = -1.0;
w[i+21][28] = -1.0;
w[28][i+3] = 1.0;
w[i+15][29] = -1.0;
w[i+24][29] = -1.0;
w[29][i+6] = 1.0;
w[9+4*i][30] = -1.0;
w[18+4*i][30] = -1.0;
w[30][4*i] = 1.0;
w[11+2*i][31] = -1.0;
w[20+2*i][31] = -1.0;
w[31][2+2*i] = 1.0;
w[9+3*i][32] = -1.0;
w[18+3*i][32] = -1.0;
w[32][3*i] = 1.0;
w[10+3*i][33] = -1.0;
w[19+3*i][33] = -1.0;
w[33][1+3*i] = 1.0;
w[11+3*i][34] = -1.0;
w[20+3*i][34] = -1.0;
w[34][2+3*i] = 1.0;
}
/* friendly doubleton detectors */
for(i = 0; i < 3; i++)
{ w[i+9][35] = 1.0;
w[i+18][35] = -2.0;
w[35][i] = 5.0;
w[i+12][36] = 1.0;
w[i+21][36] = -2.0;
w[36][i+3] = 5.0;
w[i+15][37] = 1.0;
w[i+24][37] = -2.0;
w[37][i+6] = 5.0;
w[9+4*i][38] = 1.0;
w[18+4*i][38] = -2.0;
w[38][4*i] = 5.0;
w[11+2*i][39] = 1.0;
w[20+2*i][39] = -2.0;
w[39][2+2*i] = 5.0;
w[9+3*i][40] = 1.0;
w[18+3*i][40] = -2.0;
w[40][3*i] = 5.0;
w[10+3*i][41] = 1.0;
w[19+3*i][41] = -2.0;
w[41][1+3*i] = 5.0;
w[11+3*i][42] = 1.0;
w[20+3*i][42] = -2.0;
w[42][2+3*i] = 5.0;
}
/* enemy doubleton detectors */
for(i = 0; i < 3; i++)
{ w[i+9][43] = -2.0;
w[i+18][43] = 1.0;
w[43][i] = 1.0;
w[i+12][44] = -2.0;
w[i+21][44] = 1.0;
w[44][i+3] = 1.0;
w[i+15][45] = -2.0;
w[i+24][45] = 1.0;
w[45][i+6] = 1.0;
w[9+4*i][46] = -2.0;
w[18+4*i][46] = 1.0;
w[46][4*i] = 1.0;
w[11+2*i][47] = -2.0;
w[20+2*i][47] = 1.0;
w[47][2+2*i] = 1.0;
w[9+3*i][48] = -2.0;
w[18+3*i][48] = 1.0;
w[48][3*i] = 1.0;
w[10+3*i][49] = -2.0;
w[19+3*i][49] = 1.0;
w[49][1+3*i] = 1.0;
w[11+3*i][50] = -2.0;
w[20+3*i][50] = 1.0;
w[50][2+3*i] = 1.0;
}
/* friendly singleton detectors */
for(i = 0; i < 3; i++)
{ w[i+9][51] = 1.0;
w[i+18][51] = -2.0;
w[51][i] = 2.0;
w[i+12][52] = 1.0;
w[i+21][52] = -2.0;
w[52][i+3] = 2.0;
w[i+15][53] = 1.0;
w[i+24][53] = -2.0;
w[53][i+6] = 2.0;
w[9+4*i][54] = 1.0;
w[18+4*i][54] = -2.0;
w[54][4*i] = 2.0;
w[11+2*i][55] = 1.0;
w[20+2*i][55] = -2.0;
w[55][2+2*i] = 2.0;
w[9+3*i][56] = 1.0;
w[18+3*i][56] = -2.0;
w[56][3*i] = 2.0;
w[10+3*i][57] = 1.0;
w[19+3*i][57] = -2.0;
w[57][1+3*i] = 2.0;
w[11+3*i][58] = 1.0;
w[20+3*i][58] = -2.0;
w[58][2+3*i] = 2.0;
}
/* enemy singleton detectors */
for(i = 0; i < 3; i++)
{ w[i+9][59] = -2.0;
w[i+18][59] = 1.0;
w[59][i] = 2.0;
w[i+12][60] = -2.0;
w[i+21][60] = 1.0;
w[60][i+3] = 2.0;
w[i+15][61] = -2.0;
w[i+24][61] = 1.0;
w[61][i+6] = 2.0;
w[9+4*i][62] = -2.0;
w[18+4*i][62] = 1.0;
w[62][4*i] = 2.0;
w[11+2*i][63] = -2.0;
w[20+2*i][63] = 1.0;
w[63][2+2*i] = 2.0;
w[9+3*i][64] = -2.0;
w[18+3*i][64] = 1.0;
w[64][3*i] = 2.0;
w[10+3*i][65] = -2.0;
w[19+3*i][65] = 1.0;
w[65][1+3*i] = 2.0;
w[11+3*i][66] = -2.0;
w[20+3*i][66] = 1.0;
w[66][2+3*i] = 2.0;
}
/* biases */
for(i = 0; i < 9; i++)
bias[i] = 0.0625;
for(i = 0; i < 8; i++)
{ bias[i+27] = 0.5;
bias[i+35] = -1.5;
bias[i+43] = -1.5;
bias[i+51] = -0.5;
bias[i+59] = -0.5;
}
for(i = 0; i < N; i++)
{ bias[i] *= SCALE;
for(j = 0; j < N; j++)
w[i][j] *= SCALE;
}
#ifdef DEBUG
for(i = 0; i < N; i++)
{
for(j = 0; j < N; j++)
printf("%2.0f",w[i][j]);
printf("%7.2f\n",bias[i]);
}
#endif
}

randint(n)
int n;
/* return a random integer in the range 0 to n-1 */
{
return(rand() % n);
}

#define MAXSIZE 5
boxes(a,n)
float a[];
int n;
/* Draw boxes proportional to activation levels (a) ala Hinton diagrams.
* If n equals N then draw all N boxes otherwise draw only the nth.
*/
{
int i,j,k,x,y,x0,y0;
int size,count;

x0 = 5;
y0 = 40;
count = -1;
for(k = 0; k < 3; k++)
{ x = x0;
y = y0;
for(i = 0; i < 3; i++)
{ for(j = 0; j < 3; j++)
{ x += 12;
count++;
if(n == N || n == count)
{ size = a[count]*MAXSIZE;
_setcolor(0);
_rectangle(_GFILLINTERIOR,
x-MAXSIZE,y-MAXSIZE,x+MAXSIZE,y+MAXSIZE);
_setcolor(15);
_rectangle(_GBORDER,x-size,y-size,x+size,y+size);
}
}
x = x0;
y += 12;
}
x0 += 48;
}
y0 = 40;
for(k = 0; k < 5; k++)
{ x = x0;
y = y0;
for(i = 0; i < 3; i++)
{ for(j = 0; j < 3; j++)
{ x += 12;
if(i != 1 || j != 1)
{ count++;
if(n == N || n == count)
{ size = a[count]*MAXSIZE;
_setcolor(0);
_rectangle(_GFILLINTERIOR,
x-MAXSIZE,y-MAXSIZE,x+MAXSIZE,y+MAXSIZE);
_setcolor(15);
_rectangle(_GBORDER,x-size,y-size,x+size,y+size);
}
}
}
x = x0;
y += 12;
}
x0 += 48;
}
}

drawboard()
{ static char board[5][6] = {32,179,32,179,32,0,
196,197,196,197,196,0,
32,179,32,179,32,0,
196,197,196,197,196,0,
32,179,32,179,32,0};
int i;
_clearscreen(_GCLEARSCREEN);
for(i = 0; i < 5; i++)
{ _settextposition(i+8,37);
_outtext(&board[i][0]);
}
_settextposition(2,2);
_outtext("move x o empty 2x 2o 1x 1o");
_settextposition(19,5);
_outtext("Use arrow keys to move cursor.");
_settextposition(20,5);
_outtext("ENTER will change the marker under the cursor. x is program, o is opponent.");
_settextposition(21,5);
_outtext("ESCAPE will start network.");
_settextposition(22,5);
_outtext("After network is started, any key will stop.");
_settextposition(23,5);
_outtext("ESCAPE while network is running will exit program");
}

putmarkers(b,x)
float b[]; /* board description vector for input to network */
int x; /* location of programs new move */
/*
* puts x's and o's on the board
* x is the programs marker,
* o is the opponents marker
*/
{ int i,row,col;
static int board[9] = {0};
int c, c1;
/* place the programs new move on the board */
if(x > -1)
{ _settextposition(8+2*(x/3),37+2*(x%3));
_outtext("x");
board[x] = 1;
}
/* get the users input to the new board description */
row = 8;
col = 37;
i = 0;
_settextposition(row,col);
_displaycursor(_GCURSORON);
while((c = getch()) != 27) /* continue until escape is hit */
{ switch(c)
{ case 13: /* enter key */
{ board[i] = (board[i]+1)%3;
if(board[i] == 0)
_outtext(" ");
else if(board[i] == 1)
_outtext("x");
else
_outtext("o");
_settextposition(row,col);
break;
}
case 0:
{ c1 = getch();
switch(c1)
{ case 72: /* up arrow */
{ if(row > 8)
{ row -= 2;
i -= 3;
_settextposition(row,col);
break;
}
}
case 75: /* left arrow */
{ if(col > 37)
{ col -= 2;
i--;
_settextposition(row,col);
break;
}
}
case 77: /* right arrow */
{ if(col < 41)
{ col += 2;
i++;
_settextposition(row,col);
break;
}
}
case 80: /* down arrow */
{ if(row < 12)
{ row += 2;
i += 3;
_settextposition(row,col);
break;
}
}
}
}
}
}
_displaycursor(_GCURSOROFF);
for(i = 0; i < 9; i++)
{ switch(board[i])
{ case 0:
{ b[i] = 0.0;
b[i+9] = 0.0;
break;
}
case 1:
{ b[i] = 1.0;
b[i+9] = 0.0;
break;
}
case 2:
{ b[i] = 0.0;
b[i+9] = 1.0;
break;
}
}
}
}
 case 2:
{ b[i] = 0.0;
b[i+9] = 1.0;
break;
}


  3 Responses to “Category : C Source Code
Archive   : TTT.ZIP
Filename : TTT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/