~ubuntu-branches/ubuntu/edgy/pouetchess/edgy-updates

« back to all changes in this revision

Viewing changes to src/scene_main_game.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc (mr_pouit)
  • Date: 2006-07-15 15:45:57 UTC
  • Revision ID: james.westby@ubuntu.com-20060715154557-3paxq02hx4od0wm4
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2006 by Frederic MARTIN                                 *
 
3
 *   martin-frederic@users.sourceforge.net                                 *
 
4
 *                                                                         *
 
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.                                   *
 
9
 *                                                                         *
 
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.                          *
 
14
 *                                                                         *
 
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
 ***************************************************************************/
 
20
 
 
21
 
 
22
#include "scene_main_game.h"
 
23
#include "utils.h"
 
24
#include "faile/faile.h"
 
25
#include "faile/protos.h"
 
26
#include "faile/extvars.h"
 
27
 
 
28
 
 
29
//--------------------------------------------------//
 
30
//--------------------------------------------------//
 
31
//         **  E_scene_main_game **                 //
 
32
//--------------------------------------------------//
 
33
//--------------------------------------------------//
 
34
 
 
35
E_scene_main_game::E_scene_main_game()
 
36
{
 
37
        chessboard              = NULL;
 
38
}
 
39
 
 
40
E_scene_main_game::~E_scene_main_game()
 
41
{
 
42
 
 
43
}
 
44
                
 
45
 
 
46
bool E_scene_main_game::load()
 
47
{
 
48
        if (already_loaded)
 
49
                return true;
 
50
        
 
51
        clearScreen();
 
52
        pGlobalInfos->GUI_SetEvenListener(this);
 
53
        
 
54
        AINew();
 
55
        switch (pGlobalInfos->GetAILevel())
 
56
        {
 
57
                case 0:
 
58
                        min_per_game=3;// Add 1 second for animation time ;)
 
59
                        break;
 
60
                        
 
61
                case 7:
 
62
                        min_per_game=90;
 
63
                        break;
 
64
                        
 
65
                default:
 
66
                        min_per_game=pGlobalInfos->GetAILevel()*10;
 
67
                        break;
 
68
        }
 
69
#ifdef DEBUG
 
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);
 
72
#endif
 
73
 
 
74
        
 
75
        //TODO : check pGlobalInfos to see if the player want 2D or 3D interface
 
76
        chessboard = new C3DGraphicChessboard(); // 3D Chessboard
 
77
        chessboard->load();
 
78
        
 
79
        SquareXSelected=-1;
 
80
        SquareZSelected=-1;
 
81
        FutureXSquare=-1;
 
82
        FutureZSquare=-1;
 
83
        
 
84
        pGlobalInfos->GUI_setScene(GUI_SCENE_MAIN_GAME);
 
85
        pGlobalInfos->GUI_displayResult(no_result);
 
86
 
 
87
        
 
88
        player_color  = WHITE;
 
89
        current_color = player_color;
 
90
        game_mode = pGlobalInfos->GetGameMode();
 
91
                                        
 
92
        game_is_over=false;
 
93
        promotion=false;
 
94
        piece_for_promotion='q';
 
95
        
 
96
        FAILE_AI_thread=NULL;
 
97
        AI_comp_is_done=false;
 
98
        
 
99
        init_fade_out();
 
100
        fade_out=true;
 
101
        fade_in=false;
 
102
        
 
103
        finish_loading();
 
104
        return true;
 
105
}
 
106
 
 
107
 
 
108
 
 
109
void E_scene_main_game::unload()
 
110
{
 
111
        if (already_loaded==false)
 
112
                return;
 
113
        
 
114
        if (FAILE_AI_thread)
 
115
        {
 
116
                pouetChess_asks_FAILE_to_exit = TRUE;
 
117
                SDL_WaitThread(FAILE_AI_thread,NULL);
 
118
        }
 
119
        
 
120
        chessboard->unload();
 
121
        SAFE_DELETE(chessboard);
 
122
        
 
123
        already_loaded=false;
 
124
}
 
125
 
 
126
 
 
127
 
 
128
 
 
129
 
 
130
void E_scene_main_game::update()
 
131
{
 
132
        if (already_loaded==false)
 
133
        {
 
134
                if ( load()==false )
 
135
                {
 
136
                        Logger::writeErrorLog("Loading of 'E_scene_main_game' failed: exiting...");
 
137
                        pGlobalInfos->QuitGame();
 
138
                        return;
 
139
                }
 
140
        }
 
141
        
 
142
        chessboard->display(board_to_display);
 
143
                
 
144
        click_on_chessboard(pGlobalInfos->MouseX(), pGlobalInfos->MouseY());
 
145
        
 
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))
 
149
        {
 
150
                pGlobalInfos->ReleaseKeys();
 
151
                
 
152
                if (SquareXSelected>-1 && SquareZSelected>-1)
 
153
                {
 
154
                        SquareXSelected=-1;
 
155
                        SquareZSelected=-1;
 
156
                }
 
157
                else
 
158
                {
 
159
                        // go back to main menu
 
160
                        scene_to_go=GAME_SCENE_MAIN_MENU;
 
161
                        init_fade_in();
 
162
                        fade_in=true;
 
163
                }
 
164
        }
 
165
        
 
166
        
 
167
        
 
168
        if (AI_comp_is_done)
 
169
        {
 
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'));
 
175
                
 
176
                if (result!=no_result)
 
177
                {
 
178
                        game_is_over=true;
 
179
                        pGlobalInfos->GUI_displayResult(result);
 
180
                }
 
181
                
 
182
                if (current_color == WHITE)
 
183
                        current_color=BLACK;
 
184
                else
 
185
                        current_color=WHITE;
 
186
        }
 
187
        
 
188
 
 
189
        go_2D();
 
190
        
 
191
        glDisable(GL_TEXTURE_2D);
 
192
        
 
193
        
 
194
        pGlobalInfos->GUI_updateEvents();
 
195
        pGlobalInfos->GUI_render();
 
196
        
 
197
        glEnable(GL_BLEND);
 
198
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
199
        
 
200
        if (fade_out)
 
201
                fade_out=gl_fade_out(pGlobalInfos->ElapsedTime()/200.0f);
 
202
        
 
203
 
 
204
        if (fade_in)
 
205
        {
 
206
                if (!gl_fade_in(pGlobalInfos->ElapsedTime()/200.0f))
 
207
                {
 
208
                        // At the end of the fade_in we have to load the next scene
 
209
                        fade_in=false;
 
210
                        unload();
 
211
                        pGlobalInfos->SetCurrentScene(scene_to_go);
 
212
                        clearScreen();
 
213
                }
 
214
        }
 
215
 
 
216
        exit_2D();
 
217
        
 
218
        
 
219
        SDL_Delay(5);
 
220
        
 
221
 
 
222
}
 
223
 
 
224
 
 
225
 
 
226
 
 
227
void E_scene_main_game::click_on_chessboard(int mouseX, int mouseY)
 
228
{
 
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))
 
231
                return;
 
232
        
 
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
 
235
        if (promotion)
 
236
                return;
 
237
        
 
238
        // if the game is over, there is no reason to play anymore :)
 
239
        if (game_is_over)
 
240
                return;
 
241
        
 
242
                
 
243
        int sqX, sqY;
 
244
        
 
245
        
 
246
        if (pGlobalInfos->OnLeftMouseButtonDown())
 
247
        {       
 
248
                if (chessboard->clickOnChessBoard(mouseX,mouseY,&sqX,&sqY));
 
249
                {
 
250
                        // if a piece was already selected, this means the player want to move this piece
 
251
                        if (SquareXSelected>-1 && SquareZSelected>-1)
 
252
                        {
 
253
                                FutureXSquare=sqX;
 
254
                                FutureZSquare=sqY;
 
255
                                
 
256
                                // check if the player move is legal (ie: move is in possible_moves array)
 
257
                                if (move_is_legal())
 
258
                                {
 
259
                                        // check if the move will be a promotion
 
260
                                        check_for_promotion();
 
261
                                        
 
262
                                        // if so, wait for the player to answer to which piece 
 
263
                                        // he wants for the promotion
 
264
                                        if (promotion)
 
265
                                                return;
 
266
                                        
 
267
                                        player_do_a_move(0);
 
268
                                                                
 
269
                                        
 
270
                                        if (game_is_over)
 
271
                                                return;
 
272
                                                                                        
 
273
                                        // ------- MODE PLAYER_VS_PLAYER -------
 
274
                                        if (game_mode == PLAYER_VS_PLAYER)
 
275
                                                chessboard->changeSideToPlay(current_color);
 
276
                                        
 
277
 
 
278
                                        // ------- MODE PLAYER_VS_AI -------
 
279
                                        if (game_mode == PLAYER_VS_AI)
 
280
                                        {               
 
281
                                                thread_data[0]=&AI_comp_is_done;
 
282
                                                thread_data[1]=move_to_do;
 
283
                                                
 
284
                                                FAILE_AI_thread=SDL_CreateThread(AIComputeMove,thread_data);
 
285
                                        }
 
286
                                        return;
 
287
                                }
 
288
                        }
 
289
                        // if no piece were previously selected 
 
290
                        SquareXSelected=-1;
 
291
                        SquareZSelected=-1;
 
292
                        
 
293
                        int pos=24 + (sqY+1)*12 -(sqX+3);
 
294
                        if (pos>=0 && pos<145)
 
295
                        {
 
296
                                bool color_selected=board_to_display[pos]%2;
 
297
                                
 
298
                                if (current_color!=WHITE)
 
299
                                        color_selected=!color_selected;
 
300
                                                        
 
301
                                if (color_selected && board_to_display[pos]!=npiece && board_to_display[pos]!=frame)
 
302
                                {
 
303
                                        SquareXSelected=sqX;
 
304
                                        SquareZSelected=sqY;
 
305
                                        UpdatePossibleMoves(SquareXSelected,SquareZSelected);
 
306
                                }
 
307
                        }
 
308
                        
 
309
                }
 
310
        }
 
311
        
 
312
        if (pGlobalInfos->display_possible_moves() && SquareXSelected>-1 && SquareZSelected>-1)
 
313
                chessboard->displayPossibleMoves(SquareXSelected,SquareZSelected,possible_moves);
 
314
}
 
315
 
 
316
 
 
317
 
 
318
 
 
319
 
 
320
 
 
321
void E_scene_main_game::check_for_promotion()
 
322
{
 
323
        // First check dest 
 
324
        if (current_color == WHITE && FutureZSquare != 7)
 
325
                return;
 
326
        if (current_color == BLACK && FutureZSquare != 0)
 
327
                return; 
 
328
        
 
329
        
 
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)
 
334
        {
 
335
                bool color_selected=board_to_display[pos]%2;
 
336
                
 
337
                if (current_color!=WHITE)
 
338
                        color_selected=!color_selected;
 
339
                                        
 
340
                if (color_selected) // if the selected piece is owned by the current player
 
341
                {
 
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)
 
344
                                return;
 
345
                }
 
346
                
 
347
        }
 
348
        
 
349
        
 
350
        // here we are sure that a pawn is selected and its
 
351
        // destination deserves a promotion
 
352
        // So enable promotion !
 
353
        promotion = true;
 
354
        pGlobalInfos->GUI_displayPromotion(true);
 
355
                
 
356
}
 
357
 
 
358
 
 
359
void E_scene_main_game::player_do_a_move(char promotion)
 
360
{
 
361
        // Inform FAILE of the move
 
362
        char piece_pos[6];
 
363
 
 
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
 
369
        piece_pos[5]=0;
 
370
 
 
371
        Player_do_a_move(piece_pos);
 
372
        // Update the graphical interface
 
373
        chessboard->Move_piece(SquareXSelected+8*SquareZSelected,FutureXSquare+8*FutureZSquare);
 
374
 
 
375
        if (game_mode == PLAYER_VS_PLAYER)
 
376
        {
 
377
                update_result();
 
378
                
 
379
                if (result!=no_result)
 
380
                {
 
381
                        game_is_over=true;
 
382
                        pGlobalInfos->GUI_displayResult(result);
 
383
                }
 
384
        }
 
385
                                        
 
386
        
 
387
        SquareXSelected=-1;
 
388
        SquareZSelected=-1;
 
389
        FutureXSquare=-1;
 
390
        FutureZSquare=-1;
 
391
        
 
392
        if (current_color == WHITE)
 
393
                current_color = BLACK;
 
394
        else
 
395
                current_color = WHITE;
 
396
}
 
397
 
 
398
 
 
399
 
 
400
void E_scene_main_game::update_result()
 
401
{
 
402
        
 
403
        /* check for draw by the 50 move rule: */
 
404
        if (fifty > 100) 
 
405
        {
 
406
                result = draw_by_fifty;
 
407
                return;         
 
408
        }
 
409
        else if (is_draw ()) 
 
410
        {
 
411
                result = draw_by_rep;
 
412
                return;
 
413
        }
 
414
        
 
415
        
 
416
        move_s moves[MOVE_BUFF];
 
417
        int num_moves, i, ep_temp;
 
418
        d_long temp_hash;
 
419
 
 
420
        ep_temp = ep_square;
 
421
        temp_hash = cur_pos;
 
422
        num_moves = 0;
 
423
        gen (&moves[0], &num_moves);
 
424
        
 
425
        // for all possible moves for all pieces
 
426
        for (i = 0; i < num_moves; i++) 
 
427
        {
 
428
                // if the move is from the side of the current player
 
429
                bool color=moves[i].from%2;
 
430
                if (current_color==WHITE)
 
431
                        color=!color;
 
432
                
 
433
                // if the selected piece is not owned by the current player, continue
 
434
                if (!color) 
 
435
                        continue;
 
436
                
 
437
                // test if the move is legal
 
438
                make (&moves[0], i);
 
439
                bool legal=check_legal (&moves[0], i); 
 
440
                
 
441
                unmake (&moves[0], i);
 
442
                ep_square = ep_temp;
 
443
                cur_pos = temp_hash;
 
444
                
 
445
                // if we find a legal move, game can continue
 
446
                if (legal)
 
447
                        return;
 
448
        }       
 
449
        
 
450
        
 
451
        // if we are here, it means that there is no
 
452
        // move avaible for the current player
 
453
        if (in_check ())
 
454
        {
 
455
                if (white_to_move == 1)
 
456
                        result = white_is_mated;
 
457
                else 
 
458
                        result = black_is_mated;
 
459
        }
 
460
        else 
 
461
        {
 
462
                result = stalemate;
 
463
        }
 
464
        
 
465
}
 
466
 
 
467
 
 
468
void E_scene_main_game::UpdatePossibleMoves(unsigned char posX, unsigned char posZ)
 
469
{
 
470
        for(int i=0;i<32;i++)
 
471
                possible_moves[i]=99;
 
472
        
 
473
        int j=0;
 
474
        
 
475
        char piece_pos[2];
 
476
        
 
477
        // convert pouetChess coordinates to FAILE coordinates
 
478
        piece_pos[0]=(unsigned char)('h'-posX);
 
479
        piece_pos[1]=(unsigned char)(posZ+'1');
 
480
 
 
481
        
 
482
        move_s moves[MOVE_BUFF];
 
483
        int num_moves, i, ep_temp;
 
484
        char comp_move[6];
 
485
        d_long temp_hash;
 
486
 
 
487
        ep_temp = ep_square;
 
488
        temp_hash = cur_pos;
 
489
        num_moves = 0;
 
490
        gen (&moves[0], &num_moves);
 
491
 
 
492
        // for all possible moves for all pieces
 
493
        for (i = 0; i < num_moves; i++) 
 
494
        {
 
495
                comp_to_coord (moves[i], comp_move);
 
496
                
 
497
                // if the move is from the piece we want
 
498
                if ((comp_move[0]==piece_pos[0]) && (comp_move[1]==piece_pos[1]))
 
499
                {
 
500
                        // test if the move is legal
 
501
                        make (&moves[0], i);
 
502
                        if (check_legal (&moves[0], i)) 
 
503
                        {
 
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;    
 
508
                        }
 
509
                        unmake (&moves[0], i);
 
510
                        ep_square = ep_temp;
 
511
                        cur_pos = temp_hash;
 
512
                }
 
513
        }
 
514
}
 
515
 
 
516
 
 
517
 
 
518
bool E_scene_main_game::move_is_legal()
 
519
{
 
520
        for(int i=0;i<32;i++)
 
521
                if (possible_moves[i]==FutureXSquare+8*FutureZSquare)
 
522
                        return true;
 
523
        return false;
 
524
}
 
525
 
 
526
 
 
527
 
 
528
void E_scene_main_game::actionPerformed(GUIEvent &evt)
 
529
{
 
530
        
 
531
        
 
532
        const std::string &callbackString  = evt.getCallbackString();
 
533
        GUIRectangle      *sourceRectangle = evt.getEventSource();
 
534
        int                widgetType      = sourceRectangle->getWidgetType();
 
535
 
 
536
        if(widgetType == WT_BUTTON)
 
537
        {
 
538
                GUIButton   *button = (GUIButton*)sourceRectangle;
 
539
                if(button->isClicked())
 
540
                {
 
541
                        
 
542
                        if(callbackString == "QuitMainGame")
 
543
                        {
 
544
                                scene_to_go=GAME_SCENE_MAIN_MENU;
 
545
                                init_fade_in();
 
546
                                fade_in=true;
 
547
                        }
 
548
                        
 
549
                        if (callbackString == "ResetCamera")
 
550
                        {
 
551
                                chessboard->resetCameraPos();
 
552
                        }
 
553
                        
 
554
                        if (callbackString == "okButtonPromotion")
 
555
                        {
 
556
                                player_do_a_move(piece_for_promotion);
 
557
                                pGlobalInfos->GUI_displayPromotion(false);
 
558
                                promotion=false;
 
559
                        }
 
560
                }
 
561
        }
 
562
        else if (widgetType == WT_RADIO_BUTTON)
 
563
        {
 
564
                GUIRadioButton *button = (GUIRadioButton*)sourceRectangle;
 
565
                
 
566
                if(button->isClicked())
 
567
                {
 
568
                        
 
569
                        if(callbackString == "queen")
 
570
                                piece_for_promotion='q';
 
571
                        
 
572
                        if(callbackString == "rook")
 
573
                                piece_for_promotion='r';
 
574
                        
 
575
                        if(callbackString == "bishop")
 
576
                                piece_for_promotion='b';
 
577
                        
 
578
                        if(callbackString == "knight")
 
579
                                piece_for_promotion='n';
 
580
                }
 
581
                
 
582
        }
 
583
}
 
584
 
 
585
 
 
586
 
 
587
 
 
588