Octave, 453
format plus 'XO.'
disp(F=zeros(6))
r=@()fread(0,1);R=@()r()-47;q=@(m)printf(m)&&quit;e=@()q("INVALID");l=@(n)n<1||n>6&&e();s=@()r()==32||e();w="P1 WINS";f=@(v)abs(sum(v))==22.5&&q(w);g=@(m)any(abs(sum(m))==22.5)&&q(w);d=@diag;while 1
i=R();i==66&&quit;l(i);s();l(j=R());s();F(j,i)&&e();abs(v=R()-36.5)==4.5||e();F(j,i)=v;disp(F)
r();f(d(F,-1));f(d(F,0)(2:6));f(d(F,0)(1:5));f(d(F,1));g(F(1:5,:));g(F(2:6,:));g(F(:,1:5)');g(F(:,2:6)');F&&q("P2 WINS");end
The implementation is quite straightforward, the only real “trick” to use format plus
to take care of printing.
Here is a commented version:
format plus 'XO.' # this is where the magic happens
## initialize and print empty board
disp(F=zeros(6))
## shortcuts
r=@()fread(0,1);
R=@()r()-47;
q=@(m)printf(m)&&quit;
e=@()q("INVALID");
l=@(n)n<1||n>6&&e();
s=@()r()==32||e();
w="P1 WINS";
f=@(v)abs(sum(v))==22.5&&q(w);
g=@(m)any(abs(sum(m))==22.5)&&q(w);
d=@diag;
while 1
i=R(); # read index 1
i==66&&quit; # ‘q’?
l(i); # check bounds
s(); # read and check space
l(j=R()); # read and check index 2
s(); # read and check space
F(j,i)&&e(); # square already filled?
abs(v=R()-36.5)==4.5||e(); # valid mark?
F(j,i)=v; # assign …
disp(F) # and print board
r(); # read off newline
## check diagonals
f(d(F,-1));
f(d(F,0)(2:6));
f(d(F,0)(1:5));
f(d(F,1));
## check rows
g(F(1:5,:));
g(F(2:6,:));
## check columns
g(F(:,1:5)');
g(F(:,2:6)');
## check chaos
F&&q("P2 WINS");
end
I took care to output the board and messages in a tidy manner. If some extra output is acceptable, I could shave off a couple of bytes. For example, using automatic printing (no disp(F)
), the board would be shown as
F =
......
......
......
......
......
......
Also, I interpreted that each move is given on a separate line.