1/***************************************************************************
2* KBlocks, a falling blocks game for KDE *
3* Copyright (C) 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> *
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#include "KBlocksSinglePlayer.h"
11
12KBlocksSinglePlayer::KBlocksSinglePlayer(GamePlayerInterface * player, int thinkInterval, int processInterval)
13{
14 mpPlayer = player;
15 mpGame = 0;
16
17 mPlayerState = KBlocksPlayer_ThinkingState;
18
19 mThinkInterval = thinkInterval;
20 mProcessInterval = (processInterval < 0) ? 0 : processInterval;
21 if (mThinkInterval >= 0)
22 {
23 mActionTimer.setInterval(thinkInterval);
24 connect(&mActionTimer, SIGNAL(timeout()), this, SLOT(doAction()));
25 }
26 mActionTimer.stop();
27
28 mActionList.clear();
29}
30
31KBlocksSinglePlayer::~KBlocksSinglePlayer()
32{
33}
34
35void KBlocksSinglePlayer::startGame(SingleGameInterface * p)
36{
37 mpGame = p;
38 mpPlayer->startGame(mpGame);
39
40 mPlayerState = KBlocksPlayer_ThinkingState;
41
42 mActionList.clear();
43
44 if (mThinkInterval > 0)
45 {
46 mActionTimer.start();
47 }
48}
49
50void KBlocksSinglePlayer::stopGame()
51{
52 mActionTimer.stop();
53
54 mActionList.clear();
55
56 mpPlayer->stopGame();
57 mpGame = 0;
58}
59
60void KBlocksSinglePlayer::pauseGame(bool flag)
61{
62 if (flag)
63 {
64 mActionTimer.stop();
65 }
66 else if (mThinkInterval > 0)
67 {
68 mActionTimer.start();
69 }
70}
71
72void KBlocksSinglePlayer::think()
73{
74 mActionList.clear();
75 mpPlayer->think(&mActionList);
76
77 if ((!mActionList.empty()) && (mThinkInterval > 0))
78 {
79 mActionTimer.stop();
80 mActionTimer.setInterval(mProcessInterval);
81 mPlayerState = KBlocksPlayer_ProcessingState;
82 mActionTimer.start();
83 }
84}
85
86bool KBlocksSinglePlayer::process()
87{
88 if (mActionList.empty())
89 {
90 if (mThinkInterval > 0)
91 {
92 mActionTimer.stop();
93 mActionTimer.setInterval(mThinkInterval);
94 mPlayerState = KBlocksPlayer_ThinkingState;
95 mActionTimer.start();
96 }
97 return false;
98 }
99
100 if (!mpGame->isActive())
101 {
102 return false;
103 }
104
105 KBlocks_Player_Action tmpAction = mActionList.front();
106 mActionList.pop_front();
107 switch(tmpAction)
108 {
109 case PlayerAction_Move_Left:
110 mpGame->setCurrentPiece(-1, 0, 0);
111 break;
112 case PlayerAction_Move_Right:
113 mpGame->setCurrentPiece(1, 0, 0);
114 break;
115 case PlayerAction_Move_Down:
116 mpGame->setCurrentPiece(0, 1, 0);
117 break;
118 case PlayerAction_Push_Down:
119 while(mpGame->setCurrentPiece(0, 1, 0)) ;
120 mpGame->forceUpdateGame();
121 break;
122 case PlayerAction_Rotate_CW:
123 mpGame->setCurrentPiece(0, 0, 1);
124 break;
125 case PlayerAction_Rotate_CCW:
126 mpGame->setCurrentPiece(0, 0, -1);
127 break;
128 case PlayerAction_None:
129 default:
130 break;
131 }
132
133 return true;
134}
135
136void KBlocksSinglePlayer::doAction()
137{
138 if (!mpGame)
139 {
140 return;
141 }
142
143 if (mPlayerState == KBlocksPlayer_ThinkingState)
144 {
145 think();
146 }
147 else if (mPlayerState == KBlocksPlayer_ProcessingState)
148 {
149 process();
150 }
151}
152
153