Permainan Catur & Cara Pembuatannya

Posted: 1 Juni 2010 in SoftSkill Teknologi Game

Catur adalah permainan yang dimainkan antara dua pemain . Permainan ini dimainkan pada papan catur , yang merupakan papan kotak-kotak persegi dengan 64 kuadrat diatur dalam sebuah-oleh-delapan grid delapan. Pada awalnya, tiap pemain kontrol enam belaspotongan : satu raja , satu ratu , dua rooks , dua kesatria , dua uskup , dan delapan pion . Tujuan permainan ini adalah untuk sekakmatlawan raja, dimana raja adalah serangan langsung (di ” cek “) dan tidak ada cara untuk menghapus atau mempertahankannya dari serangan pada langkah berikutnya.

Bentuk permainan saat ini muncul di Eropa pada paruh kedua abad ke-15 setelah berevolusi dari game yang lebih tua ( Shatranj ) dariIndia asal. Aspek seni dapat ditemukan dalam komposisi catur . Teoretikus telah mengembangkan luas catur strategi dan taktikpermainan sejak awal itu. Salah satu tujuan awal para ilmuwan komputer adalah untuk menciptakan mesin-bermain catur . Catur sekarang sangat dipengaruhi oleh kemampuan dari program catur dan kesempatan untuk bermain online. Pada tahun 1997 Deep Bluemenjadi komputer pertama yang mengalahkan seorang memerintah Juara Dunia dalam pertandingan ketika mengalahkan Garry Kasparov.

Tradisi catur kompetitif terorganisir dimulai pada abad ke-16. Resmi pertama Juara Catur Dunia , Wilhelm Steinitz , mengklaim gelar pada tahun 1886; Juara Dunia saat ini adalah Viswanathan Anand . Catur adalah olahraga yang diakui dari Komite Olimpiade Internasional , dan dipimpin oleh FIDE . Hari ini, catur merupakan salah satu dunia yang paling populer games, dimainkan oleh jutaan orang di seluruh dunia di rumah, di klub , online, melalui korespondensi , dan di turnamen .


Aturan Permainan

Catur dimainkan di kotak papan delapan baris (disebut barisan dan dilambangkan dengan angka 1 sampai 8) dan delapan kolom (disebut file dan dilambangkan dengan huruf a,untuk h) kuadrat. Warna kotak enam puluh empat alternatif dan disebut sebagai “kotak cahaya” dan “kotak gelap”. papan catur tersebut ditempatkan dengan kotak cahaya di ujung sebelah kanan terdekat peringkat ke setiap pemain, dan potongan-potongan ditetapkan seperti yang ditunjukkan di diagram, dengan masing-masing ratu pada warna sendiri.

Potongan dibagi, dengan konvensi, ke set putih dan hitam. Para pemain yang disebut sebagai ” White “dan” Black “, dan masing-masing permainan dimulai dengan enam belas potongan warna yang ditentukan. Ini terdiri dari satu raja , satu ratu , dua rooks , dua uskup , dua kesatria dan delapan pion .

Sebelum bertanding, pecatur memilih warna buah yang akan ia mainkan. Pemegang buah putih memulai langkah pertama, yang selanjutnya diikuti oleh pemegang buah hitam secara bergantian. Tujuan permainan adalah mencapai posisi skak mat. Hal ini bisa terjadi bila Raja terancam dan tidak bisa menyelamatkan diri ke petak lain. Tidak selalu permainan berakhir dengan kekalahan, karena bisa terjadi pula peristiwa seri atau remis di mana kedua belah pihak tidak mampu lagi meneruskan pertandingan karena tidak bisa mencapai skak mat. Peristiwa remis ini bisa terjadi berdasarkan kesepakatan maupun tidak. Salah satu contoh remis yang tidak berdasarkan kesepakatan – tetapi terjadi adalah pada keadaan remis abadi. Keadaan remis yang lain adalah keadaan pat, dimana yang giliran melangkah tidak bisa melangkahkan buah apapun termasuk Raja, tetapi tidak dalam keadaan terancam skak. Dalam pertandingan catur pihak yang menang biasanya mendapatkan nilai 1, yang kalah 0, sedang draw 0.5.


Algoritma Dalam Sebuah Game Catur

1. PENDAHULUAN

Tree search adalah salah satu algoritma inti dalam banyak program permainan game. Tree search melihat semua kemungkinan yang ada dalam permainan sebagai pohon, dengan langkah legal dalam permainan sebagai akar dari pohon-pohon tersebut. Daun dari pohon-pohon yang ada merupakan posisi terakhir dari permainan, di mana hasil dari permainan sudah dapat diketahui. Masalah yang dihadapi dalam menyusun sebuah algoritma permainan adalah ukuran dari pohon permainan ini sangatlah besar, dapat dirumuskan sebagai W^D, di mana W adalah rata-rata jumlah langkah yang legal dalam satu posisi, dan D adalah kedalaman dari sebuah pohon. Melakukan pencarian terhadap keseluruhan pohon adalah mustahil, terutama karena keterbatasan waktu yang ada, bahkan untuk komputer tercepat sekalipun. Maka dari itu penggunaan algoritma yang tepat untuk melakukan pencarian terhadap pohon didasarkan pada menghindari pencarian terhadap seluruh pohon. Berbagai algoritma pencarian berikut digambarkan menggunakan pengantar bahasa C. Variable serta fungsi yang ada memiliki arti sebagai berikut.

1.1 Chess Tree Search

Dalam sebuah permainan catur menentukan langkah terbaik dapat dilihat sebagai suatu proses searching dalam sebuah pohon. Pada akar pohon kita mencari posisi successor terbaik untuk dijalankan oleh pemain pada tingkat selanjutnya kita mencari posisi successorterbaik berdasarkan dari posisi musuh, dst.


Pencarian dari keseluruhan pohon akan menghasilkanW^D kali perhitungan seperti sudah dijelaskan sebelumnya. Hal ini tentunya mustahil mengingat banyaknya langkah yang mungkin dalam suatu permainan catur (semakin banyak langkah yang mungkin dalam permainan mengakibatkan menignkatnya nilai dari W dan D).


1.2. Solusi

Solusi untuk permasalahan chess search tree beragam.Salah satunya adalah algoritma minmax negamax dimana semua kemungkinan langkah dihitung kemungkinannya. Selain itu juga ada alpha-beta search di mana nilai dari suatu posisi hanya dihitungapabila nilai dari posisi tersebut lebih baik atau lebih buruk dari posisi yang didapat sebelumnya. Juga principal variation search yang merupakan pengembangan dari alpha-beta search.


2.PEMBAHASAN ALGORITMA

2.1. MiniMax dan NegaMax

NegaMax adalah struktur fundamental di mana menjadi dasar bagi setiap algoritma pencarian terhadap chess tree. NegaMax mengimplementasikan pemikiran bahwa semakin buruk langkah yang dilakukan oleh lawan artinya langkah yang kita lakukan semakin baik.

Mengimplementasikan pemikiran ini sebenarnya mudah. Pemikiran ini menggunakan dasar bahwa catur adalah sebuah permainan symmetrical, oleh sebab itu maka fungsi analisis haruslah mengeluarkan nilai yang simetris. Jadi pada setiap posisi nilai dari langkah yang dilakukan oleh putih adalah negasi dari langkah yang dilakukan oleh hitam, atau bisa dibilang bahwa jumlah dari nilai keduanya adalah 0.

Apabila putih unggul satu pion maka sudah jelas bahwa hitam tertinggal sebanyak jumlah yang sama.Prinsip yang sama dapat diperluas ke dalam keunggulan posisi, misalnya putih memiliki dua benteng dalam satu garis yang sama maka putih mendapatkan poin tambahan, pada saat yang sama posisi hitam menjadi lebih lemah dengan jumlah yang sama karena hal ini.

Dasar dari algoritma ini adalah bahwa chess treesearch merupakan pergantian antara maksimalisasi dan minimalisasi nilai dari posisi pada pohon; biasa disebut dengan proses minimax. Untuk membedakan posisi antara pemain dengan lawannya, nilai dari suatu posisi selalu dievaluasi dari sudut pandang pemainyang akan berjalan, hal ini dilakukan dengan melakukan negasi terhadap nilai yang dilihat oleh lawan; ini disebut dengan proses negamax. Proses ini bila digambarkan dengan pseudo code bahasa yang mirip dengan C menjadi seperti berikut.

Jumlah posisi yang harus dihitung menggunakan algoritma ini adalah W^D, di mana W adalah lebar dari pohonnya (jumlah rata-rata langkah yang mungkin pada setiap posisi) dan D adalah kedalaman pohonnya (^ menunjukkan pengeksponensialan). Ini sangatlah tidak efisien dan akan menghambat bahkan super computer sekaligus untuk mencapai tingkat kedalaman yang tinggi.

2.2. Alpha-Beta Search

Alpha-Beta search adalah suatu teknik untuk mengurangi secara besar-besaran ukuran dari pohon pencarian. Dengan menggunakan algoritma NegaMax kita melakukan pencarian semua jawaban terhadap semua langkah dalama permainan. Rata-rata permainan catur memiliki 30 langkah legal, asumsikan program menganalisis 50.000 langkah tiap detiknya.Mari kita lihat seberapa dalam pencarian dapat dilakukan.


Pembuatan “Game Catur Sederhana”

Disini saya akan membagi ilmu tentang pembuatan game catur sederhana menggunakan bahasa pemrograman C/C++. Disini saya akan menjelaskan mengenai aplikasi pohon n-ary dalam membuat algoritma suatu game catur. Penggunaan pohon terutama terlihat jelas melalui pembukaan dalam sebuah permainan catur dimana gerakan yang legal masih belum terlalu banyak.

BOARD

#define NOATOM

#define NOCLIPBOARD

#define NOCREATESTRUCT

#define NOSOUND

#define NOWH

#define NOWINOFFSETS

#define NOCOMM

#define NOKANJI

#include <windows.h>

#include <stdio.h>

#include “defs.h”

/* All units defined in pixels */

#define BRD_HORZFRONT 48

#define BRD_HORZBACK 32

#define BRD_VERT 32

#define BRD_EDGE 8

#define BRD_HORZMARGIN 32

#define BRD_BACKMARGIN 5

#define BRD_FRONTMARGIN 5

static void DrawOneSquare ( HDC hDC, int x, int y);

static int HilitSq;

void QueryBoardSize ( POINT *pptl )

{

pptl->x = 2*BRD_HORZMARGIN + 8*BRD_HORZFRONT;

pptl->y = BRD_BACKMARGIN + 8*BRD_VERT + 2*BRD_FRONTMARGIN + 2*BRD_EDGE;

}

void QuerySqSize ( POINT *pptl ) {

pptl->x = BRD_HORZFRONT;

pptl->y = BRD_VERT;

}

void QuerySqOrigin (int x, int y, POINT *pptl)

{

pptl->x = BRD_HORZMARGIN + y * (BRD_HORZFRONT-BRD_HORZBACK)/2 +

x * (y*BRD_HORZBACK + (8-y)*BRD_HORZFRONT)/8;

pptl->y = (BRD_BACKMARGIN+8*BRD_VERT+BRD_FRONTMARGIN) – y*BRD_VERT;

}

void QuerySqCoords (int x, int y, POINT aptl[] )

{

QuerySqOrigin ( x, y, aptl+0);

QuerySqOrigin ( x+1,y, aptl+1);

QuerySqOrigin ( x+1,y+1,aptl+2);

QuerySqOrigin ( x, y+1,aptl+3);

}

static void DrawOneSquare ( HDC hDC, int x, int y)

{

POINT aptl[4];

QuerySqCoords ( x,y, aptl);

Polygon( hDC, aptl, 4);

}

/*

Draw the board. Pass the routine the upper left connor and the

colors to draw the squares.

*/

void Draw_Board ( HDC hDC, int reverse,

DWORD DarkColor, DWORD LightColor )

{

int x, y, OldPolyMode;

HBRUSH hOldBrush, hBrush_lt, hBrush_dk;

HPEN hOldPen;

POINT aptl[4];

hBrush_lt = CreateSolidBrush ( LightColor );

hBrush_dk = CreateSolidBrush ( DarkColor );

hOldBrush = SelectObject ( hDC, hBrush_lt);

hOldPen = SelectObject ( hDC, GetStockObject (BLACK_PEN) );

OldPolyMode = SetPolyFillMode ( hDC, WINDING );

for (y=0; y<8; y++) {

for (x=0; x<8; x++) {

if ( reverse == 0 ) {

SelectObject ( hDC, ((x+y)&1) ? hBrush_lt : hBrush_dk);

DrawOneSquare (hDC, x, y);

} else {

SelectObject ( hDC, (((7-x)+(7-y))&1) ? hBrush_lt : hBrush_dk);

DrawOneSquare (hDC, 7-x, 7-y);

}

}

}

/* Now draw the bottom edge of the board */

for (x=0; x<8; x++) {

QuerySqCoords ( x,0, aptl);

aptl[2].x = aptl[1].x;

aptl[2].y = aptl[1].y + BRD_EDGE;

aptl[3].x = aptl[0].x;

aptl[3].y = aptl[0].y + BRD_EDGE;

SelectObject ( hDC, (x&1) ? hBrush_lt : hBrush_dk);

Polygon ( hDC, aptl, 4 );

}

SetPolyFillMode (hDC, OldPolyMode);

SelectObject (hDC, hOldPen);

SelectObject (hDC, hOldBrush);

DeleteObject ( hBrush_lt);

DeleteObject ( hBrush_dk);

}

void DrawCoords ( HDC hDC, int reverse, DWORD clrBackGround, DWORD clrText)

{

HFONT hFont, hOldFont;

int i, OldBkMode;

DWORD OldBkColor, OldTextColor;

int xchar, ychar;

POINT pt;

TEXTMETRIC tm;

hFont = CreateFont ( 13, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,

ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, FIXED_PITCH | FF_SWISS, “Helv” );

hOldFont = SelectObject ( hDC, hFont);

OldBkColor = SetBkColor ( hDC, clrBackGround);

OldBkMode = SetBkMode ( hDC, TRANSPARENT);

OldTextColor = SetTextColor (hDC, clrText);

GetTextMetrics ( hDC, &tm);

xchar = tm.tmMaxCharWidth;

ychar = tm.tmHeight;

for ( i=0; i<8; i++) {

QuerySqOrigin (0, i, &pt );

TextOut (hDC, pt.x-xchar, pt.y-BRD_VERT/2-ychar/2,

(reverse ? “87654321”+i : “12345678”+i) ,1);

QuerySqOrigin (i,0, &pt );

TextOut (hDC, pt.x+BRD_HORZFRONT/2-xchar/2, pt.y+BRD_EDGE,

(reverse ? “hgfedcba”+i : “abcdefgh”+i), 1);

}

SelectObject (hDC, hOldFont);

DeleteObject ( hFont);

SetBkColor ( hDC, OldBkColor);

SetBkMode ( hDC, OldBkMode);

SetTextColor (hDC, OldTextColor);

}

void DrawWindowBackGround ( HDC hDC, HWND hWnd, DWORD bkcolor)

{

RECT rect;

HBRUSH hBrush, hOldBrush;

hBrush = CreateSolidBrush ( bkcolor);

hOldBrush = SelectObject ( hDC, hBrush);

GetClientRect ( hWnd, &rect);

FillRect ( hDC, &rect, hBrush);

SelectObject ( hDC, hOldBrush);

DeleteObject ( hBrush);

}

void HiliteSquare ( HWND hWnd, int Square )

{

HDC hDC;

int x,y;

POINT aptl[4];

HRGN hRgn;

y = Square / 8;

x = Square % 8;

QuerySqCoords ( x,y, aptl+0);

hRgn = CreatePolygonRgn( aptl, 4, WINDING);

hDC = GetDC ( hWnd);

InvertRgn ( hDC, hRgn );

ReleaseDC ( hWnd, hDC );

DeleteObject ( hRgn);

HilitSq = Square;

}

void UnHiliteSquare ( HWND hWnd, int Square )

{

HDC hDC;

int x,y;

POINT aptl[4];

HRGN hRgn;

if ( HilitSq == -1 ) return;

y = Square / 8;

x = Square % 8;

QuerySqCoords ( x,y, aptl+0);

hRgn = CreatePolygonRgn( aptl, 4, WINDING);

hDC = GetDC ( hWnd);

InvertRgn ( hDC, hRgn );

ReleaseDC ( hWnd, hDC );

DeleteObject ( hRgn);

HilitSq = -1;

}

CHESS

*/

#include <windows.h> /* required for all Windows applications */

#include <string.h>

#include <time.h>

#include “gnuchess.h”

#include “defs.h”

#include “chess.h”

#include “saveopen.h”

#include “color.h”

DWORD clrBackGround; /* rgb structures for various colors */

DWORD clrBlackSquare;

DWORD clrWhiteSquare;

DWORD clrBlackPiece;

DWORD clrWhitePiece;

DWORD clrText;

static HBRUSH hBrushBackGround;

int boarddraw[64]; /* Display copies of the board */

int colordraw[64]; /* Needed because while computer is calculating*/

/* moves it updates board and color thus you can*/

/* not repaint the screen accuratly */

struct PIECEBITMAP pieces[7];

HANDLE hInst; /* current instance */

char szAppName[] = “Chess”;

extern char mvstr[4][6];

extern GLOBALHANDLE hBook;

int coords = 1;

static int FirstSq = -1; /* Flag is a square is selected */

static int GotFirst = FALSE;

static int EditActive = FALSE; /* Edit mode? */

static int User_Move = TRUE; /* User or computer’s turn */

static HMENU hMainMenu;

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,

int nCmdShow);

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,

int nCmdShow)

{

HWND hWnd;

MSG msg;

POINT pt;

lpCmdLine ++;

if (!hPrevInstance)

if (!ChessInit(hInstance)) return( FALSE );

hInst = hInstance; /* Saves the current instance */

QueryBoardSize (&pt);

/* Create the mailn window. It will be autosized in WM_CREATE message */

hWnd = CreateWindow(szAppName, szAppName,

WS_OVERLAPPEDWINDOW, // | WS_CLIPCHILDREN,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL);

if (!hWnd) return( FALSE );

ShowWindow(hWnd, nCmdShow); /* Shows the window */

/* Initialize chess */

if (init_main ( hWnd ) ) {

SMessageBox (hWnd, IDS_INITERROR,IDS_CHESS);

FreeGlobals ();

return( FALSE );

}

UpdateWindow(hWnd); /* Sends WM_PAINT message */

player = opponent;

ShowSidetoMove ();

while (GetMessage(&msg, NULL, 0, 0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return( (int) msg.wParam ); /* Returns the value from PostQuitMessage */

}

LONG APIENTRY ChessWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)

{

FARPROC lpProcAbout;

HMENU hMenu;

PAINTSTRUCT ps;

HDC hDC;

TEXTMETRIC tm;

int i;

POINT point;

OFSTRUCT pof;

char FileName[256], str[80];

DWORD Status;

HANDLE hFile;

switch (message) {

case WM_CREATE: { /* message: window being created */

int xchar, ychar;

GetStartupColors ( szAppName);

hBrushBackGround = CreateSolidBrush ( clrBackGround );

for ( i=pawn; i<pawn+6; i++ ) pieces[i].piece = LoadBitmap (hInst, MAKEINTRESOURCE(PAWNBASE+i));

for ( i=pawn; i<pawn+6; i++ ) pieces[i].mask = LoadBitmap (hInst, MAKEINTRESOURCE(PAWNBASE+6+i));

for ( i=pawn; i<pawn+6; i++ ) pieces[i].outline = LoadBitmap (hInst, MAKEINTRESOURCE(PAWNBASE+12+i));

hDC = GetDC (hWnd);

GetTextMetrics ( hDC, &tm);

xchar = tm.tmMaxCharWidth;

ychar = tm.tmHeight+tm.tmExternalLeading;

/*Autosize main window */

QueryBoardSize (&point);

SetWindowPos( hWnd, hWnd, 0,0,

point.x+GetSystemMetrics(SM_CXFRAME)*2+50,

point.y+GetSystemMetrics(SM_CYFRAME)*2+GetSystemMetrics(SM_CYMENU)+

GetSystemMetrics(SM_CYCAPTION) + ychar,

SWP_NOMOVE | SWP_NOZORDER);

ReleaseDC ( hWnd, hDC);

InitHitTest ();

Create_Children ( hWnd, hInst, xchar, ychar);

break;

}

case WM_DESTROY: /* message: window being destroyed */

DeleteObject (hBrushBackGround);

Hittest_Destructor ();

if ( hBook ) FreeBook();

FreeGlobals ();

SaveColors ( szAppName);

PostQuitMessage(0);

break;

case WM_PAINT:

if ( FirstSq != -1 ) { /*Properly repaint hilighted square*/

POINT pt; RECT rect;

QuerySqOrigin ( FirstSq%8, FirstSq/8, &pt);

rect.left = pt.x; rect.right=pt.x+48;

rect.top = pt.y-48; rect.bottom = pt.y;

InvalidateRect (hWnd, &rect, FALSE);

}

hDC = BeginPaint ( hWnd, &ps);

Draw_Board ( hDC, flag.reverse, clrBlackSquare, clrWhiteSquare );

if ( coords ) DrawCoords ( hDC, flag.reverse, clrBackGround, clrText);

DrawAllPieces ( hDC, flag.reverse, boarddraw, colordraw, clrBlackPiece, clrWhitePiece );

EndPaint ( hWnd, &ps);

if ( FirstSq != -1 ) HiliteSquare ( hWnd, FirstSq);

break;

case WM_CTLCOLORSTATIC: /*Enable setting colors for the message controls*/

{

POINT point;

// UnrealizeObject ( hBrushBackGround ); ***KENT***

SetBkColor ((HDC)wParam, clrBackGround);

SetBkMode ((HDC)wParam, TRANSPARENT);

SetTextColor ((HDC)wParam, clrText);

point.x = point.y = 0;

ClientToScreen (hWnd, &point);

SetBrushOrgEx ((HDC)wParam, point.x, point.y, &point);

return ((LONG) hBrushBackGround);

}

case WM_ERASEBKGND:

{

RECT rect;

// UnrealizeObject ( hBrushBackGround); ***KENT***

GetClientRect ( hWnd, &rect);

FillRect ( (HDC)wParam, &rect, hBrushBackGround);

return 1;

}

case WM_INITMENUPOPUP:

if ( User_Move ) { /*Abort thinklook ahead*/

flag.timeout = true;

flag.bothsides = false;

}

if ( !EditActive ) Init_Menus (hWnd, wParam, lParam);

break;

case WM_LBUTTONDOWN:

/* If computer is thinking on human’s time stop it at the first

button click. add test to ensure that “human” can’t interupt

the computer from thinking through its turn */

if ( User_Move ) {

flag.timeout = true;

flag.bothsides = false;

}

/* Don’t continue unless reason to */

if ( !(EditActive || User_Move)) break;

point.x = LOWORD(lParam);

point.y = HIWORD(lParam);

{

int Hit;

Hit = HitTest (point.x, point.y );

if ( Hit == -1 ){

if ( FirstSq != -1) {

UnHiliteSquare ( hWnd, FirstSq);

GotFirst = FALSE;

FirstSq = -1;

}

break;

}

if ( GotFirst ) {

UnHiliteSquare( hWnd, FirstSq);

GotFirst = FALSE;

if ( EditActive == TRUE) {

PostMessage ( hWnd, MSG_EDITBOARD,((FirstSq<<8)|Hit), (LONG) NULL);

} else if ( User_Move == TRUE) {

PostMessage ( hWnd, MSG_USER_ENTERED_MOVE, ((FirstSq<<8)|Hit), (LONG) NULL);

}

FirstSq = -1;

} else {

GotFirst = TRUE;

FirstSq = Hit;

HiliteSquare ( hWnd, Hit);

}

}

break;

case MSG_EDITBOARD:

{

int Square, First;

if ( flag.reverse ) {

First = 63 – ((wParam>>8) & 0xff);

Square = 63 – (wParam & 0xff);

} else {

First = (wParam>>8) & 0xff;

Square = wParam & 0xff;

}

board[Square] = board[First];

color[Square] = color[First];

board[First] = no_piece;

color[First] = neutral;

UpdateDisplay (hWnd, First, Square, false, false);

}

break;

case MSG_USER_MOVE:

if ( flag.bothsides && !flag.mate ) {

SelectMove ( hWnd, opponent, 1);

if ( flag.beep ) MessageBeep (0);

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

} else if (!flag.mate) {

User_Move = TRUE;

ft = 0;

player = opponent;

ShowSidetoMove ();

{

/* Set up to allow computer to think while user takes move*/

int tmp; unsigned int mv; char s[10];

if ( hint>0 && !flag.easy && Book == NULL) {

time0 = time ( NULL);

algbr ( hint>>8, hint&0xff, false);

lstrcpy ( s, mvstr[0]);

tmp = epsquare;

if ( VerifyMove (hWnd, s,1, &mv) ) {

SelectMove ( hWnd, computer, 2);

VerifyMove ( hWnd, mvstr[0], 2, &mv);

if ( Sdepth>0 ) Sdepth –;

}

ft = time (NULL) – time0;

epsquare = tmp;

}

}

}

break;

case MSG_USER_ENTERED_MOVE:

{

int temp; unsigned int mv; int Square,First; char str[10];

int algbr_flag;

User_Move = FALSE;

player = opponent;

/* Fix coord’s if user “reversed” board */

if ( flag.reverse ) {

First = 63 – ((wParam>>8) & 0xff);

Square = 63 – (wParam & 0xff);

} else {

First = (wParam>>8) & 0xff;

Square = wParam & 0xff;

}

/* Logic to allow selection for pawn promotion */

if ( (board[First] == pawn) &&( (Square <8) || (Square>55)) ) {

algbr_flag = promote + PromoteDialog (hWnd, hInst);

} else algbr_flag = 0;

algbr ( First, Square, algbr_flag);

strcpy ( str, mvstr[0] );

temp = VerifyMove ( hWnd, str, 0, &mv);

if ( temp && (mv != hint)) {

Sdepth = 0;

ft = 0;

ElapsedTime (1);

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

} else if ( temp == TRUE) {

ElapsedTime (1);

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

} else PostMessage ( hWnd, MSG_USER_MOVE, (UINT) NULL, (long)NULL);

}

break;

case MSG_COMPUTER_MOVE:

if ( !(flag.quit || flag.mate || flag.force) ) {

SelectMove ( hWnd, computer, 1);

if ( flag.beep ) MessageBeep (0);

}

PostMessage ( hWnd, MSG_USER_MOVE, (UINT) NULL, (long)NULL);

break;

/* Menu item processing */

case WM_COMMAND:

switch ( LOWORD(wParam) ) {

case MSG_CHESS_QUIT:

DestroyWindow ( hWnd);

break;

case MSG_CHESS_HINT:

GiveHint (hWnd);

break;

case MSG_CHESS_LIST:

if ( !DoFileSaveDlg ( hInst, hWnd, “chess.lst”, “.lst”, &Status,

FileName, &pof) ) break;

if ( Status == 1 ) {

strcpy ( str, “Replace Existing “);

strcat ( str, FileName);

if ( MessageBox ( hWnd, str, szAppName, MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL) == IDNO)

break;

} else OpenFile (FileName, &pof, OF_PARSE);

ListGame ( hWnd, pof.szPathName );

break;

case MSG_CHESS_SAVE:

if ( !DoFileSaveDlg ( hInst, hWnd, “chess.chs”, “.chs”, &Status,

FileName, &pof) ) break;

if ( Status == 1 ) {

strcpy ( str, “Replace Existing “);

strcat ( str, FileName);

if ( MessageBox ( hWnd, str, szAppName,

MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL) == IDNO)

break;

} else OpenFile (FileName, &pof, OF_PARSE);

SaveGame ( hWnd, pof.szPathName );

break;

case MSG_CHESS_GET:

if ( !DoFileOpenDlg ( hInst, hWnd, “*.chs”, “.chs”,0x0, FileName, &pof))

break;

if( (hFile = (HANDLE) ((LONG) OpenFile(FileName, &pof, (WORD) OF_READ|OF_REOPEN))) == ((HANDLE) -1) ) {

strcpy ( str, “Cannot open file: “);

strcat ( str, FileName);

MessageBox (hWnd, str, szAppName,

MB_OK | MB_APPLMODAL | MB_ICONQUESTION);

break;

}

CloseHandle(hFile);

GetGame ( hWnd, pof.szPathName );

break;

case MSG_CHESS_NEW:

NewGame(hWnd);

if ( hBook ) FreeBook();

GetOpenings ( hWnd);

break;

case MSG_CHESS_ABOUT:

lpProcAbout = (FARPROC) MakeProcInstance(About, hInst);

DialogBox(hInst, MAKEINTRESOURCE(AboutBox), hWnd, (WNDPROC) lpProcAbout);

FreeProcInstance(lpProcAbout);

break;

case MSG_CHESS_EDIT:

EditActive = TRUE;

hMenu = CreateMenu ();

AppendMenu ( hMenu, MF_STRING, MSG_CHESS_EDITDONE,”&Done”);

hMainMenu = GetMenu ( hWnd);

SetMenu ( hWnd, hMenu);

DrawMenuBar ( hWnd);

break;

case MSG_CHESS_EDITDONE:

EditActive = FALSE;

hMenu = GetMenu ( hWnd );

SetMenu ( hWnd, hMainMenu );

DrawMenuBar ( hWnd );

DestroyMenu ( hMenu );

GameCnt = 0;

Game50 = 1;

ZeroRPT ();

Sdepth = 0;

InitializeStats ();

PostMessage ( hWnd, MSG_USER_MOVE, (UINT) NULL, (long)NULL);

break;

case MSG_CHESS_REVIEW:

ReviewDialog ( hWnd, hInst );

break;

case MSG_CHESS_TEST:

TestDialog (hWnd, hInst);

break;

case MSG_CHESS_HASH:

flag.hash = !flag.hash;

break;

case MSG_CHESS_BEEP:

flag.beep = !flag.beep;

break;

case MSG_CHESS_COORD:

coords = !coords;

UpdateDisplay(hWnd,0,0,1,0);

break;

case MSG_CHESS_BOTH:

flag.bothsides = !flag.bothsides;

flag.easy = true;

Sdepth = 0;

PostMessage ( hWnd, MSG_USER_MOVE, (UINT) NULL, (long)NULL);

break;

case MSG_CHESS_BOOK:

if ( Book != NULL ) {

FreeBook ();

Book = NULL;

}

break;

case MSG_CHESS_POST:

if ( flag.post ) {

SendMessage ( hStats, WM_SYSCOMMAND, SC_CLOSE, 0 );

flag.post = false;

} else {

StatDialog ( hWnd, hInst);

flag.post = TRUE;

}

break;

case MSG_CHESS_AWIN: {

char str[40];

LoadString ((HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE),

IDS_SETAWIN, str, sizeof ( str ) ),

Awindow = DoGetNumberDlg ( hInst, hWnd, str, Awindow);

break;

}

case MSG_CHESS_BWIN: {

char str[40];

LoadString ((HANDLE) GetWindowLong(hWnd,GWL_HINSTANCE),

IDS_SETBWIN, str, sizeof ( str ) ),

Bwindow = DoGetNumberDlg ( hInst, hWnd, str, Bwindow);

break;

}

case MSG_CHESS_CONTEMP: {

char str[40];

LoadString ((HANDLE) GetWindowLong(hWnd,GWL_HINSTANCE),

IDS_SETCONTEMPT, str, sizeof ( str ) ),

contempt = DoGetNumberDlg ( hInst, hWnd, str, contempt);

break;

}

case MSG_CHESS_UNDO:

if ( GameCnt >0 ) Undo(hWnd);

break;

case MSG_CHESS_REMOVE:

if ( GameCnt > 1) {

Undo(hWnd); Undo (hWnd);

}

break;

case MSG_CHESS_FORCE:

computer = opponent;

opponent = otherside[computer];

ShowPlayers ();

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long) NULL);

break;

case MSG_CHESS_RANDOM:

if ( dither==0 ) dither=6; else dither = 0;

break;

case MSG_CHESS_EASY:

flag.easy = !flag.easy;

break;

case MSG_CHESS_DEPTH: {

char str[40];

LoadString ((HANDLE) GetWindowLong(hWnd,GWL_HINSTANCE),

IDS_MAXSEARCH, str, sizeof ( str ) ),

MaxSearchDepth = DoGetNumberDlg ( hInst, hWnd, str, MaxSearchDepth);

break;

}

case MSG_CHESS_REVERSE:

flag.reverse = !flag.reverse;

ShowPlayers ();

UpdateDisplay(hWnd,0,0,1,0);

break;

case MSG_CHESS_SWITCH:

computer = otherside[computer];

opponent = otherside[opponent];

flag.force = false;

Sdepth = 0;

ShowPlayers ();

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

break;

case MSG_CHESS_BLACK:

computer = black;

opponent = white;

flag.force = false;

Sdepth = 0;

ShowPlayers ();

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

break;

case MSG_CHESS_WHITE:

computer = white;

opponent = black;

flag.force = false;

Sdepth = 0;

ShowPlayers ();

PostMessage ( hWnd, MSG_COMPUTER_MOVE, (UINT) NULL, (long)NULL);

break;

case MSG_CHESS_ABORT:

flag.timeout = true;

flag.bothsides = false;

EnableMenuItem ( GetMenu(hWnd), MENU_ID_ABORT, MF_GRAYED | MF_DISABLED | MF_BYPOSITION );

DrawMenuBar ( hWnd );

break;

case IDM_BACKGROUND:

if (ColorDialog ( hWnd, hInst, wParam) ) {

InvalidateRect (hWnd, NULL, TRUE);

DeleteObject (hBrushBackGround);

hBrushBackGround = CreateSolidBrush ( clrBackGround );

/*Invalidate the text windows so they repaint */

InvalidateRect (hComputerColor, NULL, TRUE);

InvalidateRect (hComputerMove, NULL, TRUE);

InvalidateRect (hWhosTurn, NULL, TRUE);

InvalidateRect (hClockHuman, NULL, TRUE);

InvalidateRect (hClockComputer, NULL, TRUE);

InvalidateRect (hMsgComputer, NULL, TRUE);

InvalidateRect (hMsgHuman, NULL, TRUE);

}

break;

case IDM_BLACKSQUARE:

if (ColorDialog ( hWnd, hInst, wParam) ) {

InvalidateRect (hWnd, NULL, TRUE);

}

break;

case IDM_WHITESQUARE:

if (ColorDialog ( hWnd, hInst, wParam) ) {

InvalidateRect (hWnd, NULL, TRUE);

}

break;

case IDM_BLACKPIECE:

if (ColorDialog ( hWnd, hInst, wParam) ) {

InvalidateRect (hWnd, NULL, TRUE);

}

break;

case IDM_WHITEPIECE:

if (ColorDialog ( hWnd, hInst, wParam) ) {

InvalidateRect (hWnd, NULL, TRUE);

}

break;

case IDM_TEXT:

if ( ColorDialog (hWnd, hInst, wParam) ) {

/*Invalidate the text windows so they repaint */

InvalidateRect (hWnd, NULL, TRUE);

InvalidateRect (hComputerColor, NULL, TRUE);

InvalidateRect (hComputerMove, NULL, TRUE);

InvalidateRect (hWhosTurn, NULL, TRUE);

InvalidateRect (hClockHuman, NULL, TRUE);

InvalidateRect (hClockComputer, NULL, TRUE);

InvalidateRect (hMsgComputer, NULL, TRUE);

InvalidateRect (hMsgHuman, NULL, TRUE);

}

break;

case IDM_DEFAULT:

SetStandardColors ();

InvalidateRect (hWnd, NULL, TRUE);

DeleteObject (hBrushBackGround);

hBrushBackGround = CreateSolidBrush ( clrBackGround );

/*Invalidate the text windows so they repaint */

InvalidateRect (hComputerColor, NULL, TRUE);

InvalidateRect (hComputerMove, NULL, TRUE);

InvalidateRect (hWhosTurn, NULL, TRUE);

InvalidateRect (hClockHuman, NULL, TRUE);

InvalidateRect (hClockComputer, NULL, TRUE);

InvalidateRect (hMsgComputer, NULL, TRUE);

InvalidateRect (hMsgHuman, NULL, TRUE);

break;

case IDM_TIMECONTROL:

if ( TimeControlDialog (hWnd, hInst, wParam) ) {

TCflag = (TCmoves>1);

if (TCflag) {

}

SetTimeControl ();

}

break;

}

break;

default: /* Passes it on if unproccessed */

return (DefWindowProc(hWnd, message, wParam, lParam));

}

return (DefWindowProc(hWnd, message, wParam, lParam));

}

WARNA

*/

#include <windows.h>

#include <string.h>

#include <stdio.h>

#include “chess.h”

#include “color.h”

#define CBLACK RGB(0,0,0)

#define BLUE RGB(0,0,255)

#define GREEN RGB(0,255,0)

#define CYAN RGB(128,255,255)

#define RED RGB(255,0,0)

#define PINK RGB(255,0,255)

#define YELLOW RGB(255,255,0)

#define PALEGRAY RGB(192,192,192)

#define DARKGRAY RGB(127,127,127)

#define DARKBLUE RGB(0,0,128)

#define DARKGREEN RGB(0,128,0)

#define DARKCYAN RGB(0,255,255)

#define DARKRED RGB(128,0,0)

#define DARKPINK RGB(255,0,128)

#define BROWN RGB(128,128,64)

#define CWHITE RGB(255,255,255)

extern DWORD clrBackGround;

extern DWORD clrBlackSquare;

extern DWORD clrWhiteSquare;

extern DWORD clrBlackPiece;

extern DWORD clrWhitePiece;

extern DWORD clrText;

LONG APIENTRY ColorDlgProc ( HWND hDlg, UINT message,

UINT wParam, LONG lParam);

void SetStandardColors ( VOID )

{

clrBackGround = BROWN;

clrBlackSquare = DARKGREEN;

clrWhiteSquare = PALEGRAY;

clrBlackPiece = RED;

clrWhitePiece = CWHITE;

clrText = CBLACK;

}

static char lpChessini[] = “chess.ini”;

static char lpBackGround[] = “BackGround”;

static char lpBlackSquare[] = “BlackSquare”;

static char lpWhiteSquare[] = “WhiteSquare”;

static char lpBlackPiece[] = “BlackPiece”;

static char lpWhitePiece[] = “WhitePiece”;

static char lpDefault[] = “Default”;

static char lpText[] = “Text”;

static char np08lX[] = “%08lX”;

void SaveColors ( LPSTR appname )

{

char ostring[30];

wsprintf ( ostring, np08lX, clrBackGround);

WritePrivateProfileString ( appname, lpBackGround,ostring,lpChessini);

wsprintf ( ostring, np08lX, clrBlackSquare);

WritePrivateProfileString ( appname, lpBlackSquare,ostring,lpChessini);

wsprintf ( ostring, np08lX, clrWhiteSquare);

WritePrivateProfileString ( appname, lpWhiteSquare,ostring,lpChessini);

wsprintf ( ostring, np08lX, clrBlackPiece);

WritePrivateProfileString ( appname, lpBlackPiece,ostring,lpChessini);

wsprintf ( ostring, np08lX, clrWhitePiece);

WritePrivateProfileString ( appname, lpWhitePiece,ostring,lpChessini);

wsprintf ( ostring, np08lX, clrText);

WritePrivateProfileString ( appname, lpText,ostring,lpChessini);

}

void GetStartupColors ( LPSTR appname )

{

char istring[30];

SetStandardColors ();

GetPrivateProfileString ( appname, lpBackGround,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrBackGround);

GetPrivateProfileString ( appname, lpBlackSquare,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrBlackSquare);

GetPrivateProfileString ( appname, lpWhiteSquare,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrWhiteSquare);

GetPrivateProfileString ( appname, lpBlackPiece,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrBlackPiece);

GetPrivateProfileString ( appname, lpWhitePiece,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrWhitePiece);

GetPrivateProfileString ( appname, lpText,lpDefault,istring,

sizeof(istring), lpChessini);

if (strcmp ( istring, lpDefault) != 0) sscanf ( istring, np08lX, &clrText);

}

int ColorDialog ( HWND hWnd, HANDLE hInst, DWORD Param )

{

FARPROC lpProcColor;

int status;

lpProcColor = (FARPROC) MakeProcInstance(ColorDlgProc, hInst);

status = DialogBoxParam (hInst, MAKEINTRESOURCE(COLOR), hWnd, (WNDPROC) lpProcColor, Param);

FreeProcInstance(lpProcColor);

return status;

}

static int ColorToIndex ( DWORD color)

{

if (color == CBLACK ) return CNT_BLACK;

else if ( color == BLUE) return CNT_BLUE;

else if ( color == GREEN) return CNT_GREEN;

else if ( color == CYAN) return CNT_CYAN;

else if ( color == RED) return CNT_RED;

else if ( color == PINK) return CNT_PINK;

else if ( color == YELLOW) return CNT_YELLOW;

else if ( color == PALEGRAY) return CNT_PALEGRAY;

else if ( color == DARKGRAY) return CNT_DARKGRAY;

else if ( color == DARKBLUE) return CNT_DARKBLUE;

else if ( color == DARKGREEN) return CNT_DARKGREEN;

else if ( color == DARKCYAN) return CNT_DARKCYAN;

else if ( color == DARKRED) return CNT_DARKRED;

else if ( color == DARKPINK) return CNT_DARKPINK;

else if ( color == BROWN) return CNT_BROWN;

else if ( color == CWHITE) return CNT_WHITE;

return CNT_WHITE;

}

static DWORD IndexToColor ( int color)

{

if (color == CNT_BLACK ) return CBLACK;

else if ( color == CNT_BLUE) return BLUE;

else if ( color == CNT_GREEN) return GREEN;

else if ( color == CNT_CYAN) return CYAN;

else if ( color == CNT_RED) return RED;

else if ( color == CNT_PINK) return PINK;

else if ( color == CNT_YELLOW) return YELLOW;

else if ( color == CNT_PALEGRAY) return PALEGRAY;

else if ( color == CNT_DARKGRAY) return DARKGRAY;

else if ( color == CNT_DARKBLUE) return DARKBLUE;

else if ( color == CNT_DARKGREEN) return DARKGREEN;

else if ( color == CNT_DARKCYAN) return DARKCYAN;

else if ( color == CNT_DARKRED) return DARKRED;

else if ( color == CNT_DARKPINK) return DARKPINK;

else if ( color == CNT_BROWN) return BROWN;

else if ( color == CNT_WHITE) return CWHITE;

return RGB(255,0,0);

}

static char lpWBGC[] =”Window background color”;

static char lpBS[] =”Black square color”;

static char lpWS[] =”White square color”;

static char lpBP[] =”Black piece color”;

static char lpWP[] =”White piece color”;

static char lpTX[] =”Text color”;

static DWORD *pclr;

static int index;

LONG APIENTRY ColorDlgProc ( HWND hDlg, UINT message,

UINT wParam, LONG lParam)

{

char FAR *pchHeading;

switch (message) {

case WM_INITDIALOG: /* message: initialize dialog box */

switch (lParam){

default:

case IDM_BACKGROUND:

pchHeading = (char FAR *) lpWBGC;

pclr = &clrBackGround;

break;

case IDM_BLACKSQUARE:

pchHeading = (char FAR *)lpBS;

pclr = &clrBlackSquare;

break;

case IDM_WHITESQUARE:

pchHeading = (char FAR *)lpWS;

pclr = &clrWhiteSquare;

break;

case IDM_BLACKPIECE:

pchHeading = (char FAR *) lpBP;

pclr = &clrBlackPiece;

break;

case IDM_WHITEPIECE:

pchHeading = (char FAR *) lpWP;

pclr = &clrWhitePiece;

break;

case IDM_TEXT:

pchHeading = (char FAR *) lpTX;

pclr = &clrText;

break;

}

SetDlgItemText ( hDlg, IDD_HEADING, pchHeading);

index = ColorToIndex ( *pclr);

CheckRadioButton ( hDlg, CNT_BLACK, CNT_WHITE, index);

return (TRUE);

case WM_COMMAND: /* message: received a command */

switch (LOWORD(wParam)) {

case IDD_OK:

EndDialog(hDlg, 1);

*pclr = IndexToColor (index);

return TRUE;

case IDD_CANCEL:

EndDialog(hDlg, (int) NULL);

return TRUE;

case CNT_BLACK:

case CNT_BLUE:

case CNT_GREEN:

case CNT_CYAN:

case CNT_RED:

case CNT_PINK:

case CNT_YELLOW:

case CNT_PALEGRAY:

case CNT_DARKGRAY:

case CNT_DARKBLUE:

case CNT_DARKGREEN:

case CNT_DARKCYAN:

case CNT_DARKRED:

case CNT_DARKPINK:

case CNT_BROWN:

case CNT_WHITE:

index = wParam;

CheckRadioButton ( hDlg, CNT_BLACK, CNT_WHITE, index);

break;

}

break;

}

return (FALSE); /* Didn’t process a message */

}


Untuk coding selanjutnya beserta hasil Game yang sudah jadi  dapat  Anda download pada link disamping :  DOWNLOAD


HASIL OUTPUT PERMAINAN CATUR


Komentar
  1. rinrin mengatakan:

    kok pas dicompile error y ??
    minta sorce code yang lengkapnya dong mas
    ditunggu secepatnya,
    makasih

  2. tulangbelulang mengatakan:

    mas, kalo catur jawa, brarti langkah yang mungkin tiap giliran itu 5 yah?
    boardnya kayak gini

    ———-
    | \ | / |
    | \ | / |
    |— +—|
    | / | \ |
    | / | \ |
    ———-

    kebayang ga?

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s