Skip to content

Commit e49c98b

Browse files
authored
Merge pull request #3 from Dpbm/qubo-version
Qubo version
2 parents afc7593 + 8a33481 commit e49c98b

File tree

12 files changed

+458
-3
lines changed

12 files changed

+458
-3
lines changed

CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_subdirectory(game)
2525
add_subdirectory(genetic)
2626
add_subdirectory(matrix)
2727
add_subdirectory(machine)
28+
add_subdirectory(qubo)
2829
add_subdirectory(nativefiledialog-extended)
2930

3031
file(GLOB HELPERS_FILES "helpers/*.cpp")
@@ -38,6 +39,9 @@ target_link_libraries(genetic players matrix machine board helpers)
3839
file(GLOB MATRIX_FILES "matrix/*.cpp")
3940
add_library(matrix ${MATRIX_FILES})
4041

42+
file(GLOB QUBO_FILES "qubo/*.cpp")
43+
add_library(qubo ${QUBO_FILES})
44+
4145
file(GLOB MACHINE_FILES "machine/*.cpp")
4246
add_library(machine ${MACHINE_FILES})
4347
target_link_libraries(machine helpers matrix)
@@ -48,8 +52,8 @@ file(GLOB PLAYERS_FILES "game/players/*.cpp")
4852
add_library(board ${BOARD_FILE})
4953
add_library(screens ${SCREENS_FILES})
5054
add_library(players ${PLAYERS_FILES})
51-
target_link_libraries(players machine matrix genetic helpers ${SDL2_LIBRARIES})
52-
target_link_libraries(screens players board helpers genetic matrix ${SDL2_LIBRARIES} SDL2_ttf nfd)
55+
target_link_libraries(players machine matrix genetic helpers qubo ${SDL2_LIBRARIES})
56+
target_link_libraries(screens players board helpers genetic matrix qubo ${SDL2_LIBRARIES} SDL2_ttf nfd)
5357
target_link_libraries(board helpers players)
5458

5559
target_link_libraries(snake PRIVATE helpers board screens players ${SDL2_LIBRARIES} SDL2_ttf)

game/players/qubo_player.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include <cstdint>
2+
#include "qubo_player.h"
3+
#include "../../qubo/qubo.h"
4+
#include "../../helpers/utils.h"
5+
6+
using Qubo::QuboFunc;
7+
using Utils::vec2;
8+
using Utils::distance;
9+
10+
namespace Players {
11+
QuboPlayer::QuboPlayer(uint8_t board_w, uint8_t board_h) : Player(board_w, board_h){
12+
this->board_w = board_w;
13+
this->board_h = board_h;
14+
this->qubo = new QuboFunc((board_h*board_h) + 10);
15+
}
16+
17+
bool QuboPlayer::will_collide_itself(int16_t x, int16_t y){
18+
bool will_collide = false;
19+
Node* actual_bpart = this->head->next;
20+
while(actual_bpart != nullptr){
21+
22+
if(actual_bpart->value.x == x &&
23+
actual_bpart->value.y == y){
24+
will_collide = true;
25+
break;
26+
}
27+
actual_bpart = actual_bpart->next;
28+
}
29+
return will_collide;
30+
}
31+
32+
bool QuboPlayer::will_collide_top_border(){
33+
return this->get_x() <= 0;
34+
}
35+
36+
bool QuboPlayer::will_collide_bottom_border(){
37+
return this->get_x() >= this->board_h-1;
38+
}
39+
40+
bool QuboPlayer::will_collide_left_border(){
41+
return this->get_y() <= 0;
42+
}
43+
44+
bool QuboPlayer::will_collide_right_border(){
45+
return this->get_y() >= this->board_w-1;
46+
}
47+
48+
void QuboPlayer::next_mov(const vec2& food){
49+
double q0 = 10000.0; //distance forward
50+
double q1 = 10000.0; //distance down/right
51+
double q2 = 10000.0; //distance up/left
52+
53+
switch (this->dir) {
54+
case RIGHT:
55+
this->get_distances_right(food.x, food.y, &q0, &q1, &q2);
56+
break;
57+
case LEFT:
58+
this->get_distances_left(food.x, food.y, &q0, &q1, &q2);
59+
break;
60+
case UP:
61+
this->get_distances_up(food.x, food.y, &q0, &q1, &q2);
62+
break;
63+
case DOWN:
64+
this->get_distances_up(food.x, food.y, &q0, &q1, &q2);
65+
break;
66+
default:
67+
break;
68+
}
69+
70+
71+
uint8_t* next_mov = this->qubo->minimize(q0, q1, q2);
72+
73+
74+
if(next_mov[0] == 0 && next_mov[1] == 0 && next_mov[2] == 1)
75+
this->move_up_left();
76+
else if(next_mov[0] == 0 && next_mov[1] == 1 && next_mov[2] == 0)
77+
this->move_down_right();
78+
79+
delete next_mov;
80+
}
81+
82+
void QuboPlayer::get_distances_right(int16_t fx, int16_t fy, double* q0, double* q1, double* q2){
83+
if(!this->will_collide_itself(this->get_x(), this->get_y()+1) && !this->will_collide_right_border())
84+
*q0 = distance(this->get_x(), this->get_y()+1, fx, fy);
85+
86+
if(!this->will_collide_itself(this->get_x()+1, this->get_y()) && !this->will_collide_bottom_border())
87+
*q1 = distance(this->get_x()+1, this->get_y(), fx, fy);
88+
89+
if(!this->will_collide_itself(this->get_x()-1, this->get_y()) && !this->will_collide_top_border())
90+
*q2 = distance(this->get_x()-1, this->get_y(), fx, fy);
91+
}
92+
93+
94+
void QuboPlayer::get_distances_left(int16_t fx, int16_t fy, double* q0, double* q1, double* q2){
95+
if(!this->will_collide_itself(this->get_x(), this->get_y()-1) && !this->will_collide_left_border())
96+
*q0 = distance(this->get_x(), this->get_y()-1, fx, fy);
97+
98+
if(!this->will_collide_itself(this->get_x()+1, this->get_y()) && !this->will_collide_bottom_border())
99+
*q1 = distance(this->get_x()+1, this->get_y(), fx, fy);
100+
101+
if(!this->will_collide_itself(this->get_x()-1, this->get_y()) && !this->will_collide_top_border())
102+
*q2 = distance(this->get_x()-1, this->get_y(), fx, fy);
103+
}
104+
105+
void QuboPlayer::get_distances_up(int16_t fx, int16_t fy, double* q0, double* q1, double* q2){
106+
if(!this->will_collide_itself(this->get_x()-1, this->get_y()) && !this->will_collide_top_border())
107+
*q0 = distance(this->get_x()-1, this->get_y(), fx, fy);
108+
109+
if(!this->will_collide_itself(this->get_x(), this->get_y()+1) && !this->will_collide_right_border())
110+
*q1 = distance(this->get_x(), this->get_y()+1, fx, fy);
111+
112+
if(!this->will_collide_itself(this->get_x(), this->get_y()-1) && !this->will_collide_left_border())
113+
*q2 = distance(this->get_x(), this->get_y()-1, fx, fy);
114+
}
115+
116+
void QuboPlayer::get_distances_down(int16_t fx, int16_t fy, double* q0, double* q1, double* q2){
117+
if(!this->will_collide_itself(this->get_x()+1, this->get_y()) && !this->will_collide_bottom_border())
118+
*q0 = distance(this->get_x()+1, this->get_y(), fx, fy);
119+
120+
if(!this->will_collide_itself(this->get_x(), this->get_y()+1) && !this->will_collide_right_border())
121+
*q1 = distance(this->get_x(), this->get_y()+1, fx, fy);
122+
123+
if(!this->will_collide_itself(this->get_x(), this->get_y()-1) && !this->will_collide_left_border())
124+
*q2 = distance(this->get_x(), this->get_y()-1, fx, fy);
125+
}
126+
127+
128+
void QuboPlayer::move_down_right(){
129+
switch (this->dir) {
130+
case RIGHT:
131+
this->direction_down();
132+
break;
133+
case LEFT:
134+
this->direction_down();
135+
break;
136+
case UP:
137+
this->direction_right();
138+
break;
139+
case DOWN:
140+
this->direction_right();
141+
break;
142+
default:
143+
break;
144+
}
145+
}
146+
147+
void QuboPlayer::move_up_left(){
148+
switch (this->dir) {
149+
case RIGHT:
150+
this->direction_up();
151+
break;
152+
case LEFT:
153+
this->direction_up();
154+
break;
155+
case UP:
156+
this->direction_left();
157+
break;
158+
case DOWN:
159+
this->direction_left();
160+
break;
161+
default:
162+
break;
163+
}
164+
}
165+
166+
QuboPlayer::~QuboPlayer(){
167+
delete this->qubo;
168+
}
169+
170+
}

game/players/qubo_player.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#include "player.h"
4+
#include "../../qubo/qubo.h"
5+
#include "../../helpers/utils.h"
6+
#include <cstdint>
7+
8+
using Qubo::QuboFunc;
9+
using Utils::vec2;
10+
11+
namespace Players{
12+
class QuboPlayer : public Player {
13+
public:
14+
QuboPlayer(uint8_t board_w, uint8_t board_h);
15+
~QuboPlayer();
16+
17+
void next_mov(const vec2& food);
18+
19+
private:
20+
QuboFunc* qubo = nullptr;
21+
uint8_t board_w = 0;
22+
uint8_t board_h = 0;
23+
24+
bool will_collide_itself(int16_t x, int16_t y);
25+
26+
bool will_collide_top_border();
27+
bool will_collide_bottom_border();
28+
bool will_collide_left_border();
29+
bool will_collide_right_border();
30+
31+
void get_distances_right(int16_t fx, int16_t fy, double* q0, double* q1, double* q2);
32+
void get_distances_left(int16_t fx, int16_t fy, double* q0, double* q1, double* q2);
33+
void get_distances_up(int16_t fx, int16_t fy, double* q0, double* q1, double* q2);
34+
void get_distances_down(int16_t fx, int16_t fy, double* q0, double* q1, double* q2);
35+
36+
void move_down_right();
37+
void move_up_left();
38+
};
39+
40+
};

game/screens/qubo_screen.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include <SDL2/SDL_timer.h>
2+
#include <cstddef>
3+
#include <SDL2/SDL_keycode.h>
4+
#include <SDL2/SDL_render.h>
5+
#include <SDL2/SDL_ttf.h>
6+
#include <SDL2/SDL_surface.h>
7+
#include <SDL2/SDL_stdinc.h>
8+
#include <string>
9+
#include "../../helpers/constants.h"
10+
#include "qubo_screen.h"
11+
#include "start_screen.h"
12+
13+
using std::to_string;
14+
using std::cout;
15+
using std::endl;
16+
using std::size_t;
17+
18+
namespace Screens {
19+
QuboScreen::QuboScreen(SDL_Renderer* render) : Screen(render){
20+
if(!this->font){
21+
cout << "Failed on getting font!" << TTF_GetError() << endl;
22+
exit(1);
23+
}
24+
25+
SDL_Surface* score_text_surface = TTF_RenderText_Solid(this->font, "Score", this->text_color);
26+
this->score_text_texture = SDL_CreateTextureFromSurface(render, score_text_surface);
27+
this->score_text_shape = SDL_Rect{20, 20, score_text_surface->w, score_text_surface->h};
28+
SDL_FreeSurface(score_text_surface);
29+
30+
if(this->score_text_texture == nullptr){
31+
cout << "Failed on creating score text texture!" << SDL_GetError() << endl;
32+
exit(1);
33+
}
34+
this->board.add_player(this->player);
35+
this->left_padding = 10 * SQUARE_SIDE;
36+
}
37+
38+
void QuboScreen::execute(bool& game_loop){
39+
bool won = this->player->get_score() >= this->max_score;
40+
this->finished_game = won || this->player->is_dead();
41+
if(this->finished_game){
42+
SDL_Surface* game_over_surface = TTF_RenderText_Solid(this->title_font, won ? "QUBO Wins!!!" : "Game Over", this->text_color);
43+
SDL_Texture* game_over_texture = SDL_CreateTextureFromSurface(this->render, game_over_surface);
44+
SDL_Rect game_over_shape = SDL_Rect{(WIDTH/2)-(game_over_surface->w/2), (HEIGHT/2)-(game_over_surface->h), game_over_surface->w, game_over_surface->h};
45+
SDL_FreeSurface(game_over_surface);
46+
47+
SDL_Surface* reset_surface = TTF_RenderText_Solid(this->font, "Press 'r' to reset", this->text_color);
48+
SDL_Texture* reset_texture = SDL_CreateTextureFromSurface(this->render, reset_surface);
49+
SDL_Rect reset_shape = SDL_Rect{(WIDTH/2)-(reset_surface->w/2), (HEIGHT/2)+(reset_surface->h)+20, reset_surface->w, reset_surface->h};
50+
SDL_FreeSurface(reset_surface);
51+
52+
SDL_Surface* back_surface = TTF_RenderText_Solid(this->font, "Press 'g' to back to the start screen", this->text_color);
53+
SDL_Texture* back_texture = SDL_CreateTextureFromSurface(this->render, back_surface);
54+
SDL_Rect back_shape = SDL_Rect{(WIDTH/2)-(back_surface->w/2), (HEIGHT/2)+(back_surface->h)+50, back_surface->w, back_surface->h};
55+
SDL_FreeSurface(back_surface);
56+
57+
SDL_SetRenderDrawColor(this->render, 0, 0, 0, 255);
58+
SDL_RenderCopy(this->render, game_over_texture, NULL, &game_over_shape);
59+
SDL_RenderCopy(this->render, reset_texture, NULL, &reset_shape);
60+
SDL_RenderCopy(this->render, back_texture, NULL, &back_shape);
61+
SDL_DestroyTexture(game_over_texture);
62+
SDL_DestroyTexture(back_texture);
63+
SDL_DestroyTexture(reset_texture);
64+
return;
65+
}
66+
this->player->next_mov(this->board.get_food());
67+
this->board.update_player_pos();
68+
this->render_board(&this->board);
69+
70+
SDL_SetRenderDrawColor(this->render, 0, 0, 0, 255);
71+
SDL_RenderCopy(this->render, this->score_text_texture, NULL, &this->score_text_shape);
72+
73+
if(this->score_texture != nullptr)
74+
SDL_DestroyTexture(this->score_texture);
75+
SDL_Surface* score_surface = TTF_RenderText_Solid(this->font, to_string(this->player->get_score()).c_str(), this->text_color);
76+
this->score_texture = SDL_CreateTextureFromSurface(this->render, score_surface);
77+
this->score_shape = SDL_Rect{20, 60, score_surface->w, score_surface->h};
78+
SDL_FreeSurface(score_surface);
79+
80+
SDL_RenderCopy(this->render, this->score_texture, NULL, &this->score_shape);
81+
}
82+
83+
Screen* QuboScreen::key_event(const SDL_Keycode& key){
84+
switch (key) {
85+
case SDLK_g:
86+
if(this->finished_game)
87+
return new StartScreen(this->render);
88+
89+
case SDLK_r:
90+
if(this->finished_game)
91+
this->reset();
92+
93+
default:
94+
break;
95+
}
96+
return nullptr;
97+
}
98+
99+
void QuboScreen::close_event(){
100+
}
101+
102+
void QuboScreen::reset(){
103+
this->finished_game = false;
104+
delete this->player;
105+
this->player = new QuboPlayer(this->board_w, this->board_h);
106+
this->board.add_player(this->player);
107+
this->board.random_food();
108+
}
109+
110+
QuboScreen::~QuboScreen(){
111+
delete this->player;
112+
SDL_DestroyTexture(this->score_texture);
113+
SDL_DestroyTexture(this->score_text_texture);
114+
}
115+
}

0 commit comments

Comments
 (0)