1
/***************************************************************************
2
* Copyright (C) 2006 by Frederic MARTIN *
3
* martin-frederic@users.sourceforge.net *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 2 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program; if not, write to the *
17
* Free Software Foundation, Inc., *
18
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19
***************************************************************************/
22
#include "scene_main_game.h"
24
#include "faile/faile.h"
25
#include "faile/protos.h"
26
#include "faile/extvars.h"
29
//--------------------------------------------------//
30
//--------------------------------------------------//
31
// ** E_scene_main_game ** //
32
//--------------------------------------------------//
33
//--------------------------------------------------//
35
E_scene_main_game::E_scene_main_game()
40
E_scene_main_game::~E_scene_main_game()
46
bool E_scene_main_game::load()
52
pGlobalInfos->GUI_SetEvenListener(this);
55
switch (pGlobalInfos->GetAILevel())
58
min_per_game=3;// Add 1 second for animation time ;)
66
min_per_game=pGlobalInfos->GetAILevel()*10;
70
printf("AI min_per_game is set to : %ld minutes\n",min_per_game);
71
printf("A game is set to : %ld minutes\n",moves_to_tc);
75
//TODO : check pGlobalInfos to see if the player want 2D or 3D interface
76
chessboard = new C3DGraphicChessboard(); // 3D Chessboard
84
pGlobalInfos->GUI_setScene(GUI_SCENE_MAIN_GAME);
85
pGlobalInfos->GUI_displayResult(no_result);
89
current_color = player_color;
90
game_mode = pGlobalInfos->GetGameMode();
94
piece_for_promotion='q';
97
AI_comp_is_done=false;
109
void E_scene_main_game::unload()
111
if (already_loaded==false)
116
pouetChess_asks_FAILE_to_exit = TRUE;
117
SDL_WaitThread(FAILE_AI_thread,NULL);
120
chessboard->unload();
121
SAFE_DELETE(chessboard);
123
already_loaded=false;
130
void E_scene_main_game::update()
132
if (already_loaded==false)
136
Logger::writeErrorLog("Loading of 'E_scene_main_game' failed: exiting...");
137
pGlobalInfos->QuitGame();
142
chessboard->display(board_to_display);
144
click_on_chessboard(pGlobalInfos->MouseX(), pGlobalInfos->MouseY());
146
// The escape Key cancel the selection
147
// If no piece were selected when pressing escape, quit the the game
148
if (pGlobalInfos->KeyDown(SDLK_ESCAPE))
150
pGlobalInfos->ReleaseKeys();
152
if (SquareXSelected>-1 && SquareZSelected>-1)
159
// go back to main menu
160
scene_to_go=GAME_SCENE_MAIN_MENU;
170
AI_comp_is_done=false;
171
FAILE_AI_thread=NULL;
172
// update the board to display
173
memcpy (board_to_display, board, sizeof (board));
174
chessboard->Move_piece(('h'-move_to_do[0])+8*(move_to_do[1]-'1'),('h'-move_to_do[2])+8*(move_to_do[3]-'1'));
176
if (result!=no_result)
179
pGlobalInfos->GUI_displayResult(result);
182
if (current_color == WHITE)
191
glDisable(GL_TEXTURE_2D);
194
pGlobalInfos->GUI_updateEvents();
195
pGlobalInfos->GUI_render();
198
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
201
fade_out=gl_fade_out(pGlobalInfos->ElapsedTime()/200.0f);
206
if (!gl_fade_in(pGlobalInfos->ElapsedTime()/200.0f))
208
// At the end of the fade_in we have to load the next scene
211
pGlobalInfos->SetCurrentScene(scene_to_go);
227
void E_scene_main_game::click_on_chessboard(int mouseX, int mouseY)
229
// if it's not the player's turn, don't manage click on chessboard
230
if ((game_mode == PLAYER_VS_AI) && (current_color != player_color))
233
// promotion is a special state in which the player must answer
234
// to the question of what is the piece he wants for the promotion
238
// if the game is over, there is no reason to play anymore :)
246
if (pGlobalInfos->OnLeftMouseButtonDown())
248
if (chessboard->clickOnChessBoard(mouseX,mouseY,&sqX,&sqY));
250
// if a piece was already selected, this means the player want to move this piece
251
if (SquareXSelected>-1 && SquareZSelected>-1)
256
// check if the player move is legal (ie: move is in possible_moves array)
259
// check if the move will be a promotion
260
check_for_promotion();
262
// if so, wait for the player to answer to which piece
263
// he wants for the promotion
273
// ------- MODE PLAYER_VS_PLAYER -------
274
if (game_mode == PLAYER_VS_PLAYER)
275
chessboard->changeSideToPlay(current_color);
278
// ------- MODE PLAYER_VS_AI -------
279
if (game_mode == PLAYER_VS_AI)
281
thread_data[0]=&AI_comp_is_done;
282
thread_data[1]=move_to_do;
284
FAILE_AI_thread=SDL_CreateThread(AIComputeMove,thread_data);
289
// if no piece were previously selected
293
int pos=24 + (sqY+1)*12 -(sqX+3);
294
if (pos>=0 && pos<145)
296
bool color_selected=board_to_display[pos]%2;
298
if (current_color!=WHITE)
299
color_selected=!color_selected;
301
if (color_selected && board_to_display[pos]!=npiece && board_to_display[pos]!=frame)
305
UpdatePossibleMoves(SquareXSelected,SquareZSelected);
312
if (pGlobalInfos->display_possible_moves() && SquareXSelected>-1 && SquareZSelected>-1)
313
chessboard->displayPossibleMoves(SquareXSelected,SquareZSelected,possible_moves);
321
void E_scene_main_game::check_for_promotion()
324
if (current_color == WHITE && FutureZSquare != 7)
326
if (current_color == BLACK && FutureZSquare != 0)
330
// now check if the selected piece is a pawn
331
// and also check for the right color
332
int pos=24 + (SquareZSelected+1)*12 -(SquareXSelected+3);
333
if (pos>=0 && pos<145)
335
bool color_selected=board_to_display[pos]%2;
337
if (current_color!=WHITE)
338
color_selected=!color_selected;
340
if (color_selected) // if the selected piece is owned by the current player
342
// test if the selected piece is a pawn or not. If not, return
343
if (board_to_display[pos]!=wpawn && board_to_display[pos]!=bpawn)
350
// here we are sure that a pawn is selected and its
351
// destination deserves a promotion
352
// So enable promotion !
354
pGlobalInfos->GUI_displayPromotion(true);
359
void E_scene_main_game::player_do_a_move(char promotion)
361
// Inform FAILE of the move
364
piece_pos[0]=(char)('h'-SquareXSelected); // from
365
piece_pos[1]=(char)(SquareZSelected+'1'); // from
366
piece_pos[2]=(char)('h'-FutureXSquare); // target
367
piece_pos[3]=(char)(FutureZSquare+'1'); // target
368
piece_pos[4]=promotion; // promotion
371
Player_do_a_move(piece_pos);
372
// Update the graphical interface
373
chessboard->Move_piece(SquareXSelected+8*SquareZSelected,FutureXSquare+8*FutureZSquare);
375
if (game_mode == PLAYER_VS_PLAYER)
379
if (result!=no_result)
382
pGlobalInfos->GUI_displayResult(result);
392
if (current_color == WHITE)
393
current_color = BLACK;
395
current_color = WHITE;
400
void E_scene_main_game::update_result()
403
/* check for draw by the 50 move rule: */
406
result = draw_by_fifty;
411
result = draw_by_rep;
416
move_s moves[MOVE_BUFF];
417
int num_moves, i, ep_temp;
423
gen (&moves[0], &num_moves);
425
// for all possible moves for all pieces
426
for (i = 0; i < num_moves; i++)
428
// if the move is from the side of the current player
429
bool color=moves[i].from%2;
430
if (current_color==WHITE)
433
// if the selected piece is not owned by the current player, continue
437
// test if the move is legal
439
bool legal=check_legal (&moves[0], i);
441
unmake (&moves[0], i);
445
// if we find a legal move, game can continue
451
// if we are here, it means that there is no
452
// move avaible for the current player
455
if (white_to_move == 1)
456
result = white_is_mated;
458
result = black_is_mated;
468
void E_scene_main_game::UpdatePossibleMoves(unsigned char posX, unsigned char posZ)
470
for(int i=0;i<32;i++)
471
possible_moves[i]=99;
477
// convert pouetChess coordinates to FAILE coordinates
478
piece_pos[0]=(unsigned char)('h'-posX);
479
piece_pos[1]=(unsigned char)(posZ+'1');
482
move_s moves[MOVE_BUFF];
483
int num_moves, i, ep_temp;
490
gen (&moves[0], &num_moves);
492
// for all possible moves for all pieces
493
for (i = 0; i < num_moves; i++)
495
comp_to_coord (moves[i], comp_move);
497
// if the move is from the piece we want
498
if ((comp_move[0]==piece_pos[0]) && (comp_move[1]==piece_pos[1]))
500
// test if the move is legal
502
if (check_legal (&moves[0], i))
504
// convert from FAILE coords to pouetChess coords
505
unsigned char new_pos=(unsigned char)(('h'-comp_move[2])+8*(comp_move[3]-'1'));
506
// add this move to the possible moves array
507
possible_moves[j++]=new_pos;
509
unmake (&moves[0], i);
518
bool E_scene_main_game::move_is_legal()
520
for(int i=0;i<32;i++)
521
if (possible_moves[i]==FutureXSquare+8*FutureZSquare)
528
void E_scene_main_game::actionPerformed(GUIEvent &evt)
532
const std::string &callbackString = evt.getCallbackString();
533
GUIRectangle *sourceRectangle = evt.getEventSource();
534
int widgetType = sourceRectangle->getWidgetType();
536
if(widgetType == WT_BUTTON)
538
GUIButton *button = (GUIButton*)sourceRectangle;
539
if(button->isClicked())
542
if(callbackString == "QuitMainGame")
544
scene_to_go=GAME_SCENE_MAIN_MENU;
549
if (callbackString == "ResetCamera")
551
chessboard->resetCameraPos();
554
if (callbackString == "okButtonPromotion")
556
player_do_a_move(piece_for_promotion);
557
pGlobalInfos->GUI_displayPromotion(false);
562
else if (widgetType == WT_RADIO_BUTTON)
564
GUIRadioButton *button = (GUIRadioButton*)sourceRectangle;
566
if(button->isClicked())
569
if(callbackString == "queen")
570
piece_for_promotion='q';
572
if(callbackString == "rook")
573
piece_for_promotion='r';
575
if(callbackString == "bishop")
576
piece_for_promotion='b';
578
if(callbackString == "knight")
579
piece_for_promotion='n';