Finished up getting the remaining bits of my costume together last night. So now I have an orange jump suit that says “Death Row” on the front, professional grade leg irons with 15″ chain, bandana, dangly cross earing, fake tattoos.
I also hacked on WoodPusher a bit last night. I’ve now got it to the point where I can actually play a whole game of chess on an ICS server. Beautiful. And my app is now multithreaded. Read on to see the source code.
// WoodPusher.cs
//
// Author: Jamin P. Gray
//
// (c) 2003 Jamin P. Gray
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Net.Sockets;
using System.Threading;
using Gtk;
using Gdk;
using Glade;
using Gnome;
using GtkSharp;
public class WoodPusher : Gnome.Program
{
// Members
[Glade.Widget("canvas")]
private Gnome.Canvas myCanvas;
[Glade.Widget("window")]
private Gnome.App myWindow;
private int board_size = 400;
private int square_size;
private double offset_x = 0.0, offset_y = 0.0;
private double original_x = 0.0, original_y = 0.0;
private bool moving = false;
private const string VERSION = "0.01";
private Pixbuf darkSquarePixbuf;
private Pixbuf whitePawnPixbuf;
private Pixbuf whiteKnightPixbuf;
private Pixbuf whiteBishopPixbuf;
private Pixbuf whiteRookPixbuf;
private Pixbuf whiteQueenPixbuf;
private Pixbuf whiteKingPixbuf;
private Pixbuf blackPawnPixbuf;
private Pixbuf blackKnightPixbuf;
private Pixbuf blackBishopPixbuf;
private Pixbuf blackRookPixbuf;
private Pixbuf blackQueenPixbuf;
private Pixbuf blackKingPixbuf;
private Pixbuf lightSquarePixbuf;
private int counter;
private Piece[,] board = new Piece[8,8];
public struct Coordinate
{
public int x;
public int y;
}
public enum PieceType
{
Empty,
WhitePawn,
WhiteKnight,
WhiteBishop,
WhiteRook,
WhiteQueen,
WhiteKing,
BlackPawn,
BlackKnight,
BlackBishop,
BlackRook,
BlackQueen,
BlackKing
}
public struct Piece
{
public PieceType type;
public CanvasPixbuf cpb;
}
// Style 12 string (see docs/style12.txt)
public string initialBoardSetup = "<12> " +
"rnbqkbnr " +
"pppppppp " +
"-------- " +
"-------- " +
"-------- " +
"-------- " +
"PPPPPPPP " +
"RNBQKBNR " +
"W -1 1 1 1 1 0 0 White Black " +
"1 0 0 39 39 0 0 none (0:00) none 0";
private Regex style12Regex;
private Thread readThread, writeThread;
private TcpClient client;
private NetworkStream stream;
private StreamReader streamReader;
private StreamWriter streamWriter;
public static void Main ( string[] args )
{
WoodPusher app = new WoodPusher( args );
app.Run ( );
}
public WoodPusher(string[] args)
: base ("WoodPusher " + VERSION, VERSION, Modules.UI, args)
{
Glade.XML appGxml = new Glade.XML (null, "woodpusher.glade", "window", null);
appGxml.Autoconnect (this);
square_size = board_size / 8;
darkSquarePixbuf = Scale ( new Pixbuf ( "pixmaps/square.dark.png" ), square_size );
lightSquarePixbuf = Scale ( new Pixbuf ( "pixmaps/square.light.png" ), square_size );
whitePawnPixbuf = Scale ( new Pixbuf ( "pixmaps/white.pawn.png" ), square_size );
whiteKnightPixbuf = Scale ( new Pixbuf ( "pixmaps/white.knight.png" ), square_size );
whiteBishopPixbuf = Scale ( new Pixbuf ( "pixmaps/white.bishop.png" ), square_size );
whiteRookPixbuf = Scale ( new Pixbuf ( "pixmaps/white.rook.png" ), square_size );
whiteQueenPixbuf = Scale ( new Pixbuf ( "pixmaps/white.queen.png" ), square_size );
whiteKingPixbuf = Scale ( new Pixbuf ( "pixmaps/white.king.png" ), square_size );
blackPawnPixbuf = Scale ( new Pixbuf ( "pixmaps/black.pawn.png" ), square_size );
blackKnightPixbuf = Scale ( new Pixbuf ( "pixmaps/black.knight.png" ), square_size );
blackBishopPixbuf = Scale ( new Pixbuf ( "pixmaps/black.bishop.png" ), square_size );
blackRookPixbuf = Scale ( new Pixbuf ( "pixmaps/black.rook.png" ), square_size );
blackQueenPixbuf = Scale ( new Pixbuf ( "pixmaps/black.queen.png" ), square_size );
blackKingPixbuf = Scale ( new Pixbuf ( "pixmaps/black.king.png" ), square_size );
style12Regex = new Regex ( @"(\<12\>.*)" , RegexOptions.Compiled | RegexOptions.Multiline);
DrawBoard ( );
SetUpBoard ( initialBoardSetup );
ConnectToICS ( );
readThread = new Thread ( new ThreadStart ( ICSRead ) );
writeThread = new Thread ( new ThreadStart ( ICSWrite ) );
readThread.Start ( );
writeThread.Start ( );
}
// Draw the dark and light squares that make up the board
public void DrawBoard ( )
{
bool light = true;
for ( int x = 0; x < board_size; x += square_size )
{
light = !light;
for ( int y = 0; y < board_size; y += square_size )
{
light = !light;
CanvasPixbuf boardCanvasPixbuf = new CanvasPixbuf ( myCanvas.Root ( ) );
if ( light )
{
boardCanvasPixbuf.Pixbuf = lightSquarePixbuf;
}
else
{
boardCanvasPixbuf.Pixbuf = darkSquarePixbuf;
}
boardCanvasPixbuf.X = x;
boardCanvasPixbuf.Y = y;
}
}
}
// Takes a style 12 string and places the pieces on the board
public void SetUpBoard ( string s )
{
string [] fields = s.Split ( new Char [] {' '} );
for ( int y = 0; y < 8; y++ )
{
char [] characters = fields[y + 1].ToCharArray ( );
for ( int x = 0; x < 8; x++ )
{
Pixbuf piece;
switch ( characters[x] )
{
case 'p':
piece = blackPawnPixbuf;
break;
case 'n':
piece = blackKnightPixbuf;
break;
case 'b':
piece = blackBishopPixbuf;
break;
case 'r':
piece = blackRookPixbuf;
break;
case 'q':
piece = blackQueenPixbuf;
break;
case 'k':
piece = blackKingPixbuf;
break;
case 'P':
piece = whitePawnPixbuf;
break;
case 'N':
piece = whiteKnightPixbuf;
break;
case 'B':
piece = whiteBishopPixbuf;
break;
case 'R':
piece = whiteRookPixbuf;
break;
case 'Q':
piece = whiteQueenPixbuf;
break;
case 'K':
piece = whiteKingPixbuf;
break;
default:
piece = null;
break;
}
if (piece != null)
{
board[x,y].cpb = new CanvasPixbuf ( myCanvas.Root ( ) );
board[x,y].cpb.Pixbuf = piece;
board[x,y].cpb.X = x * square_size;
board[x,y].cpb.Y = y * square_size;
board[x,y].cpb.CanvasEvent += new GnomeSharp.CanvasEventHandler (Piece_Event);
}
}
}
}
// Clears all the pieces from the board
public void ClearBoard ( )
{
for ( int y = 0; y < 8; y++ )
{
for ( int x = 0; x < 8; x++ )
{
if ( board[x,y].cpb != null )
{
board[x,y].cpb.Destroy ( );
board[x,y].type = PieceType.Empty;
}
}
}
}
public Pixbuf Scale ( Pixbuf image, int size )
{
return image.ScaleSimple ( size, size, Gdk.InterpType.Bilinear );
}
// Returns the coordinates (8x8 grid) of a chess square
// given the coordinates of a point on the canvas.
public Coordinate GetCoordinates ( double x, double y )
{
Coordinate c;
c.x = (int) ( x / square_size + 1 );
c.y = (int) ( y / square_size + 1 );
if (c.x > 8 || c.y > 8 || c.x < 1 || c.y < 1) {
c.x = -1;
c.y = -1;
}
return c;
}
public void MakeMove ( Coordinate start, Coordinate end )
{
string move = "" + CoordToLetter ( start.x ) +
(9 - start.y).ToString ( ) +
CoordToLetter ( end.x ) +
(9 - end.y).ToString ( );
streamWriter.WriteLine ( move );
streamWriter.Flush ( );
}
public string CoordToLetter ( int i )
{
Console.WriteLine ( "x: {0}", i );
switch ( i )
{
case 1:
return "a";
break;
case 2:
return "b";
break;
case 3:
return "c";
break;
case 4:
return "d";
break;
case 5:
return "e";
break;
case 6:
return "f";
break;
case 7:
return "g";
break;
case 8:
return "h";
break;
default:
return "z";
break;
}
return "z";
}
public void OnWindowDeleteEvent (object o, DeleteEventArgs args)
{
Quit ( );
args.RetVal = true;
readThread.Join ( 0 );
writeThread.Join ( 0 );
Environment.Exit ( 0 );
}
void Piece_Event (object obj, GnomeSharp.CanvasEventArgs args) {
EventButton ev = EventButton.New (args.Event.Handle);
CanvasPixbuf item = (CanvasPixbuf) obj;
switch (ev.type) {
case EventType.ButtonPress:
if (ev.button == 1) {
offset_x = ev.x % square_size;
offset_y = ev.y % square_size;
original_x = ev.x;
original_y = ev.y;
args.RetVal = true;
return;
}
if (ev.button == 2) {
ClearBoard ( );
args.RetVal = true;
return;
}
break;
case EventType.ButtonRelease:
if (moving) {
Coordinate c = GetCoordinates ( ev.x, ev.y );
if (c.x != -1) {
double new_x = c.x * square_size - square_size;
double new_y = c.y * square_size - square_size;
item.X = new_x;
item.Y = new_y;
MakeMove ( GetCoordinates ( original_x, original_y ), c );
}
args.RetVal = true;
moving = false;
return;
}
break;
case EventType.MotionNotify:
Gdk.ModifierType state = (Gdk.ModifierType) ev.state;
if ((state & Gdk.ModifierType.Button1Mask) != 0) {
moving = true;
item.X = ev.x - offset_x;
item.Y = ev.y - offset_y;
args.RetVal = true;
return;
}
break;
}
args.RetVal = false;
return;
}
public void ConnectToICS ( )
{
try
{
Console.WriteLine ( "Connecting..." );
client = new TcpClient ( "freechess.org", 23 );
Console.WriteLine ( "Connected." );
stream = client.GetStream ( );
}
catch (Exception e)
{
Console.WriteLine( "Error: " + e.StackTrace );
}
}
private void ICSRead ( )
{
while ( true )
{
streamReader = new StreamReader ( stream );
string s = "";
char [] c = null;
while ( streamReader.Peek ( ) >= 0 )
{
c = new char[1];
streamReader.Read(c, 0, c.Length);
s += new String ( c );
}
Match m = style12Regex.Match ( s );
if ( m.Success )
{
Console.WriteLine ( "STYLE 12 MATCH!" );
ClearBoard ( );
string style12 = m.ToString ( );
Console.WriteLine ( "####" + s + "####" );
SetUpBoard ( style12 );
}
else
Console.Write ( s );
}
}
private void ICSWrite ( )
{
string input;
while ( true )
{
streamWriter = new StreamWriter ( stream );
input = Console.ReadLine ( );
streamWriter.WriteLine ( input );
streamWriter.Flush ( );
}
}
}
Tags: Personal










October 31st, 2003 at 4:52 pm
I was able to play a full game of chess, however, there are some serious bugs I’ve noticed since then…working on fixing…Also lots of features need to be added…