Sjakkbrett
FormMain | ChessBoard | Square | Pawns
FormMain
Klassen er laget slik at den ikke vet noe særlig om sjakkbrettet. Det eneste den gjør er å tegne opp bokstavene og siffrene som angir navn på sjakkrutene. Ansvaret for dette burde nok vært flyttet til klassen ChessBoard.
Det er FormMain som husker om vi holder på å trekke på en brikke, hvor den var sist osv. Denne logikken er imidlertid hel uavhengig av vilken brikke eller sjakkbrettets geometri.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace test1
{
public partial class FormMain : Form
{
ChessBoard Board = null;
// variables to control the moving piece
Boolean b_pieceIsMoving = false;
int LastX = -1;
int LastY = -1;
int StartX = -1;
int StartY = -1;
public FormMain()
{
InitializeComponent();
// panelBoard is squares only
Board = new ChessBoard(panelBoard.Size);
}
private void paintPanel(object sender, PaintEventArgs e)
{
// work on the panel with the chessboard
Graphics g=panelBoard.CreateGraphics();
Board.drawBoard(g);
g.Dispose();
// work on the frame(this) itself
g = this.CreateGraphics();
// produce name om rows and columns
Size s = panelBoard.Size;
int top = panelBoard.Top;
int left = panelBoard.Left;
int dx = s.Width/8;
int dy = s.Height/8;
// need a font with a color, bold and gray is ok
Font f = new Font(this.Font, FontStyle.Bold);
Brush graybrush=new SolidBrush(Color.Gray);
//north and south
for (int x = 0; x <8; x++)
{
Char ch=(char)(int)('a'+x);
String str=new String(ch,1);
g.DrawString(str, Font, graybrush,
left+dx/3+x*dx,top-15);
g.DrawString(str, Font, graybrush,
left+dx/3+x*dx, top+s.Height +5);
}
// east and west
for (int y = 8; y >0; y--)
{
String str=y.ToString();
int vpos = top + s.Height+dy/2 - y * dy;
g.DrawString(str, Font, graybrush,
left - 10, vpos);
g.DrawString(str, Font, graybrush,
left + s.Width + 5, vpos);
}
}
private void PanelMouseDown(object sender, MouseEventArgs e)
{
// left button to pick a pawn
if (e.Button == MouseButtons.Left)
{
b_pieceIsMoving = Board.PickUpPawn(e.X, e.Y);
if (b_pieceIsMoving)
{
// Capture events: all coming events routed to panel,
panelBoard.Capture = true;
LastX = e.X;
LastY = e.Y;
StartX = e.X;
StartY = e.Y;
// set move cursor
panelBoard.Cursor = new Cursor("resources/mover.cur");
}
}
}
private void PanelMouseMove(object sender, MouseEventArgs e)
{
if (b_pieceIsMoving)
{
Graphics g = panelBoard.CreateGraphics();
Board.MovePawn(e.X, e.Y,g);
// remove/show a rubberband line to indicate move in progress
ControlPaint.DrawReversibleLine(
panelBoard.PointToScreen(new Point(StartX, StartY)),
panelBoard.PointToScreen(new Point(LastX, LastY)),
SystemColors.Control);
ControlPaint.DrawReversibleLine(
panelBoard.PointToScreen(new Point(StartX, StartY)),
panelBoard.PointToScreen(new Point(e.X, e.Y)),
SystemColors.Control);
LastX = e.X;
LastY = e.Y;
}
}
private void PanelMouseUp(object sender, MouseEventArgs e)
{
panelBoard.Capture=false;
if (b_pieceIsMoving)
{
// remove the rubberband line to indicate move in progress
ControlPaint.DrawReversibleLine(
panelBoard.PointToScreen(new Point(StartX, StartY)),
panelBoard.PointToScreen(new Point(LastX, LastY)),
SystemColors.Control);
Board.DropPawn(e.X, e.Y);
Graphics g = panelBoard.CreateGraphics();
Board.drawBoard(g);
LastX = -1;
LastY = -1;
}
b_pieceIsMoving = false;
// set back cursor to hand
panelBoard.Cursor = System.Windows.Forms.Cursors.Hand;
}
private void buttonQuit_MouseClick(object sender, MouseEventArgs e)
{
this.Dispose();
}
}
}
ChessBoard
Alt som har med selve sjakkbrettet er pakket inn her.
public class ChessBoard
{
Square[,] S = new Square[8, 8];
Square fromS = null;
Square toS = null;
public ChessBoard(Size limits)
{
// set up squares
Size s = limits;
int dx = s.Width / 8;
int dy = s.Height / 8;
Color dark = Color.FromArgb(181, 148, 115);
Color lite = Color.FromArgb(214, 206, 181);
Color c = Color.Black;
for (int x = 0; x < 8; x++)
{
if (c == dark) c = lite; else c = dark;
for (int y = 0; y < 8; y++)
{
Rectangle R =
new Rectangle(x * dx, y * dy, dx, dy);
if (c == dark) c = lite; else c = dark;
S[x, y] = new Square(R, c,x,y);
}
}
// init board
initBoard();
}
public void initBoard()
{
// set up as seen from white
// white
S[0, 7].SetPiece(piece.w_rook);
S[7, 7].SetPiece(piece.w_rook);
S[6, 7].SetPiece(piece.w_knight);
S[1, 7].SetPiece(piece.w_knight);
S[5, 7].SetPiece(piece.w_bishop);
S[2, 7].SetPiece(piece.w_bishop);
S[3, 7].SetPiece(piece.w_queen);
S[4, 7].SetPiece(piece.w_king);
for (int ix = 0; ix < 8; ix++)
S[ix, 6].SetPiece(piece.w_pawn);
// black
S[0, 0].SetPiece(piece.b_rook);
S[7, 0].SetPiece(piece.b_rook);
S[6, 0].SetPiece(piece.b_knight);
S[1, 0].SetPiece(piece.b_knight);
S[5, 0].SetPiece(piece.b_bishop);
S[2, 0].SetPiece(piece.b_bishop);
S[3, 0].SetPiece(piece.b_queen);
S[4, 0].SetPiece(piece.b_king);
for (int ix = 0; ix < 8; ix++)
S[ix, 1].SetPiece(piece.b_pawn);
}
public void drawBoard(Graphics g)
{
for (int x = 0; x < 8; x++)
for (int y = 0; y < 8; y++)
S[x, y].DrawMe(g);
}
public Boolean PickUpPawn(int x, int y)
{
fromS = FindSquare(x, y);
if ((fromS != null)&&(fromS.GetPiece()!=piece.no_piece))
return true;
return false;
}
public void MovePawn(int x, int y, Graphics g)
{
// .. if we want to do something here
Square currentS = FindSquare(x, y);
}
public Boolean DropPawn(int x, int y)
{
toS = FindSquare(x, y);
if (toS == null)
return false;
// do drop action, is it a legal move
if (LegalMove(fromS, toS))
{
if (fromS != toS)
{
toS.SetPiece(fromS.GetPiece());
fromS.SetPiece(piece.no_piece);
}
return true;
}
return false;
}
private Square FindSquare(int x, int y)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (S[i, j].contains(x, y))
return S[i, j];
return null;
}
private Boolean LegalMove(Square fromS, Square toS)
{
// basis version, make sure that the squares are ok
if ((fromS == null)||(toS == null))
return false;
// we accept the move if target square is empty
if (toS.GetPiece() == piece.no_piece)
return true;
// we also accept if target square contains an opponent
if (( (fromS.GetPiece() < piece.b_king) &&
(toS.GetPiece() >= piece.b_king))
|| ((fromS.GetPiece() > piece.b_king) &&
(toS.GetPiece() <= piece.b_king)))
return true;
return false;
}
}
piece er definert slik:
public enum piece { no_piece,
w_king, w_queen, w_bishop,
w_knight, w_rook, w_pawn,
b_king, b_queen, b_bishop,
b_knight, b_rook, b_pawn};
Square
public class Square : Object
{
Rectangle R = new Rectangle();
Color C = Color.Azure;
int row = 0;
int col = 0;
int P = 0;
Char verticalName = '0';
Char horizontalName = '0';
public Square(Rectangle r, Color c,int x,int y)
{
R = r;
C = c;
row = x;
col = y;
verticalName = (char)(int)('1' + row);
horizontalName = (char)(int)('a' + col);
}
public void SetPiece(piece p)
{
P = (int)p;
}
public piece GetPiece()
{
return (piece)P;
}
public Point getPos(){
return new Point(row,col);
}
public void DrawMe(Graphics g)
{
g.FillRectangle(new SolidBrush(C), R);
g.DrawRectangle(new Pen(Color.Black), R);
g.DrawImage(Pawns.GetImage(P), new Point(R.Left, R.Top));
}
public Boolean contains(int x,int y)
{
return R.Contains(x, y);
}
public Point GetCenter(){
return new Point((int)(R.Left + R.Width / 2),
(int)(R.Top + R.Height / 2));
}
}
Pawns
public static class Pawns : Object
{
public static Image GetImage(int p)
{
switch (p)
{
case (int)piece.w_king:
return test1.Properties.Resources.wKonge;
case (int)piece.w_queen:
return test1.Properties.Resources.wDronning;
case (int)piece.w_bishop:
return test1.Properties.Resources.wLoper;
case (int)piece.w_knight:
return test1.Properties.Resources.wSpringer;
case (int)piece.w_rook:
return test1.Properties.Resources.wTarn;
case (int)piece.w_pawn:
return test1.Properties.Resources.wBonde;
case (int)piece.b_king:
return test1.Properties.Resources.bKonge;
case (int)piece.b_queen:
return test1.Properties.Resources.bDronning;
case (int)piece.b_bishop:
return test1.Properties.Resources.bLoper;
case (int)piece.b_knight:
return test1.Properties.Resources.bSpringer;
case (int)piece.b_rook:
return test1.Properties.Resources.bTarn;
case (int)piece.b_pawn:
return test1.Properties.Resources.bBonde;
default: return test1.Properties.Resources.no_piece;
}
}
}



