1 // Brain Party
2 // Copyright (C) 2010 Paul Hudson (http://www.tuxradar.com/brainparty)
3 
4 // Brain Party is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 3
7 // of the License, or (at your option) any later version.
8 
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 
18 #include "rps.h"
19 #include "Minigame.h"
20 
BPMiniGame_RPS(BPGame * game)21 BPMiniGame_RPS::BPMiniGame_RPS(BPGame* game) : BPMiniGame(game) {
22 	sfcBackground = TheGame->LoadBitmap("rockpaperscissors", 320, 416);
23 	sfcLose = TheGame->LoadBitmap("rockpaperscissors_loses", 320, 64);
24 
25 	sfcRock = TheGame->LoadBitmap("rock", 90, 90);
26 	sfcPaper = TheGame->LoadBitmap("paper", 90, 90);
27 	sfcScissors = TheGame->LoadBitmap("scissors", 90, 90);
28 
29 	LastStateChange = -1;
30 	GameState = GUESSING;
31 
32 	SuccessTime = -1;
33 
34 	CurrentPosition = NULL;
35 	PositionNum = MustWin = Tries = NumWrong = TimeStarted = 0;
36 
37 	GameTitle = "Rock vs Paper";
38 	GameHelp = "Paper beats rock, scissors beats paper and rock beats scissors - choose the right play each time. But here's the twist: sometimes you have to lose!";
39 	GameHelp2 = "You either have to WIN or you have to LOSE, so read the on-screen instructions carefully. When you have to win, your opponent will make a move (eg scissors) and you have to beat it. But when you have to lose, you need to choose whichever move would lose against your opponent's move.";
40 
41 	MiniGameType = PUZZLE;
42 
43 	Positions.Add(new BPMiniGame_RPS_Position("Rock", "Scissors", "Paper", sfcRock));
44 	Positions.Add(new BPMiniGame_RPS_Position("Paper", "Rock", "Scissors", sfcPaper));
45 	Positions.Add(new BPMiniGame_RPS_Position("Scissors", "Paper", "Rock", sfcScissors));
46 
47 	Play();
48 }
49 
~BPMiniGame_RPS()50 BPMiniGame_RPS::~BPMiniGame_RPS() {
51 	SAFE_DELETE(sfcBackground);
52 	SAFE_DELETE(sfcLose);
53 	SAFE_DELETE(sfcRock);
54 	SAFE_DELETE(sfcPaper);
55 	SAFE_DELETE(sfcScissors);
56 
57 	Positions.Clear();
58 }
59 
Play()60 void BPMiniGame_RPS::Play() {
61 	if (Tries >= 10) return;
62 
63 	Positions.Shuffle();
64 
65 	if (TheGame->RandomRange(0, 7) % 2 == 0) {
66 		MustWin = true;
67 	} else {
68 		MustWin = false;
69 	}
70 
71 	int newpos;
72 
73 	if (PositionNum == -1) {
74 		newpos = TheGame->RandomRange(0, 2);
75 	} else {
76 		newpos = TheGame->RandomRangeExcept(0, 2, PositionNum);
77 	}
78 
79 	PositionNum = newpos;
80 	CurrentPosition = Positions[newpos];
81 
82 	GameState = GUESSING;
83 }
84 
Start()85 void BPMiniGame_RPS::Start() {
86 	TimeStarted = TheGame->TickCount;
87 }
88 
GetWeight()89 int BPMiniGame_RPS::GetWeight() {
90 	int TimePassed = (TheGame->TickCount - TimeStarted) / 1000.0f;
91 	return MinMax(500 - (NumWrong * 60) - round(TimePassed * 1.55f));
92 }
93 
Render()94 void BPMiniGame_RPS::Render() {
95 	TheGame->DrawImage(sfcBackground, 0, 0);
96 
97 	if (!MustWin) TheGame->DrawImage(sfcLose, 0, 229);
98 
99 	TheGame->DrawImage(CurrentPosition->Sfc, 110, 89);
100 
101 	TheGame->DrawImage(Positions[0]->Sfc, 15, 307);
102 	TheGame->DrawImage(Positions[1]->Sfc, 115, 307);
103 	TheGame->DrawImage(Positions[2]->Sfc, 215, 307);
104 
105 	if (GameState == CORRECT) {
106 		RenderCorrect();
107 	} else if (GameState == WRONG) {
108 		RenderWrong();
109 	}
110 }
111 
Tick()112 void BPMiniGame_RPS::Tick() {
113 	if (SuccessTime != -1 && SuccessTime + 250 < TheGame->TickCount) {
114 		Success();
115 	}
116 
117 	if (LastStateChange != -1 && LastStateChange + 750 < TheGame->TickCount) {
118 		LastStateChange = -1;
119 		Play();
120 	}
121 }
122 
OnMouseDown()123 void BPMiniGame_RPS::OnMouseDown() {
124 
125 }
126 
OnMouseMove()127 void BPMiniGame_RPS::OnMouseMove() {
128 
129 }
130 
OnMouseUp()131 void BPMiniGame_RPS::OnMouseUp() {
132 	if (GameState == CORRECT || GameState == WRONG) return;
133 
134 	BPMiniGame_RPS_Position* chosenposition = NULL;
135 
136 	if (TheGame->PointOverRect(TouchEvent.X, TouchEvent.Y, 15, 307, 90, 90)) {
137 		chosenposition = Positions[0];
138 	} else if (TheGame->PointOverRect(TouchEvent.X, TouchEvent.Y, 115, 307, 90, 90)) {
139 		chosenposition = Positions[1];
140 	} else if (TheGame->PointOverRect(TouchEvent.X, TouchEvent.Y, 215, 307, 90, 90)) {
141 		chosenposition = Positions[2];
142 	} else if (TheGame->PointOverRect(TouchEvent.X, TouchEvent.Y, 110, 89, 90, 90)) {
143 		if (MustWin) {
144 			MessageBox::Show("This shows the move an opponent has played. You have been asked to choose the move that beats your opponent, so you need to tap one of the three pictures below.", GameTitle);
145 		} else {
146 			MessageBox::Show("This shows the move an opponent has played. You have been asked to choose the move that loses to your opponent, so you need to tap one of the three pictures below.", GameTitle);
147 		}
148 	} else if (TheGame->PointOverRect(TouchEvent.X, TouchEvent.Y, 0, 229, 320, 64)) {
149 		if (MustWin) {
150 			MessageBox::Show("You need to choose the right move to beat your opponent - which of the three below is the correct answer?", GameTitle);
151 		} else {
152 			MessageBox::Show("You need to choose the right move to lose to your opponent - which of the three below is the correct answer?", GameTitle);
153 		}
154 	}
155 
156 	if (chosenposition == NULL) return;
157 
158 	++Tries;
159 
160 	if (MustWin) {
161 		if (CurrentPosition->BeatenBy == chosenposition->Position) {
162 			TheGame->PlaySound("correct");
163 			GameState = CORRECT;
164 			LastStateChange = TheGame->TickCount;
165 		} else {
166 			TheGame->PlaySound("wrong");
167 			++NumWrong;
168 			GameState = WRONG;
169 			LastStateChange = TheGame->TickCount;
170 		}
171 	} else {
172 		if (CurrentPosition->Beats == chosenposition->Position) {
173 			TheGame->PlaySound("correct");
174 			GameState = CORRECT;
175 			LastStateChange = TheGame->TickCount;
176 		} else {
177 			TheGame->PlaySound("wrong");
178 			++NumWrong;
179 			GameState = WRONG;
180 			LastStateChange = TheGame->TickCount;
181 		}
182 	}
183 
184 	UpdateScore();
185 }
186 
UpdateScore()187 void BPMiniGame_RPS::UpdateScore() {
188 	if (Tries < 0) Tries = 0;
189 
190 	if (Tries >= 10 && SuccessTime == -1) {
191 		SuccessTime = TheGame->TickCount ;
192 	}
193 }
194