Memory lane: An old C program – Tic Tac Toe

less than 1 minute read

This very old program of mine, written such that the code fits into a 25 lines 80 columns terminal window, lets you play Tic Tac Toe on a \(19 \times 19\) grid:

#include <curses.h>
#define A(l) {if((m=++l[p])==1&&l[p^1])t--;if(m==5)return 1;}
#define U(v,l) {for(k=0;k<5;k++)if(!l[p^1])v[p]+=w[l[p]+1]-w[l[p]];\
else if(l[p]==1)v[p^1]-=w[l[p^1]+1];}
int b[19][19],p,t=1020,x,y,i,j,m,k,w[]={0,0,4,20,100,500,0};
struct{int s[4][2];}l[19][19]; struct{int s[2];}v[19][19];
void g(){m=b[9][9]?0:4;for(i=0;i<19;i++)for(j=0;j<19;j++)if((!b[i][j])&&(k=(*v
[i][j].s*20)/16+v[i][j].s[1]+rand()%4)>m){x=j;y=i;m=k;}}a(){b[y][x]++;for(i=0;
i<5;i++){if(x-i>=0&&x-i<15){A(l[y][x-i].s[0]);U(v[y][x-i+k].s,l[y][x-i].s[0]);
}if(y-i>=0&&y-i<15){A(l[y-i][x].s[1]);U(v[y-i+k][x].s,l[y-i][x].s[1]);}if(y-i
>=0&&x-i>=0&&y-i<15&&x-i<15){A(l[y-i][x-i].s[2]);U(v[y-i+k][x-i+k].s,l[y-i][x-
i].s[2]);}if(y-i>=0&&x+i<19&&y-i<15&&x+i>3){A(l[y-i][x+i].s[3]);U(v[y-i+k][x+i
-k].s,l[y-i][x+i].s[3]);}}return t<1?2:0;}void r(c){move(y+2,x*2+3);addch(c>1?
c:(c?'O':'X'));}void q(){while(b[y][x])(y=getch())=='x'?exit(0):(y-='a'),x=
getch()-'a';}main(){initscr();noecho();clear();srand(time(0));for(;x<19;x++){
move(x+2,1);addch('a'+x);move(1,(x+1)*2+1);addch('a'+x);}for(x=0;x<19;x++)for(
y=0;y<19;y++)r('.');for(x=y=9;;p^=1){p?q():g();r(p);if(k=a())break;}y=20;r(k>1
?'A':p?'U':'I');addstr(k>1?" DRAW":" WON");}

It still compiles using gcc version 4.7.3. Save it in a file ttt.c and compile with:

$ gcc -lncurses ttt.c -o ttt

Then take it for a spin by issuing

$ ttt