nsnake
Classic snake game for the terminal
Player.cpp
1 #include <Game/Player.hpp>
2 #include <Game/Board.hpp>
3 
4 Player::Player(int x, int y):
5  alive(true),
6  currentDirection(Player::RIGHT),
7  nextDirection(Player::RIGHT)
8 {
9  // The Snake's head
10  this->body.push_back(Body(x, y));
11 
12  // Initializing the snake with 2 body pieces
13  // (plus the head)
14  this->body.push_back(Body(x - 1, y));
15  this->body.push_back(Body(x - 1, y));
16 }
17 bool Player::isAlive()
18 {
19  return (this->alive);
20 }
21 int Player::getSize()
22 {
23  return (int)(this->body.size());
24 }
26 {
27  return (this->body.front().x);
28 }
30 {
31  return (this->body.front().y);
32 }
33 void Player::moveTo(int x, int y)
34 {
35  this->body.front().x = x;
36  this->body.front().y = y;
37 }
38 void Player::move(Direction dir)
39 {
40  this->nextDirection = dir;
41 }
42 void Player::kill()
43 {
44  this->alive = false;
45 }
46 void Player::update(Board* board)
47 {
48  // We have to make sure the snake doesn't do strange
49  // things, like turning around on itself.
50  switch(this->nextDirection)
51  {
52  case Player::RIGHT:
53  if (this->currentDirection != Player::LEFT)
54  this->currentDirection = this->nextDirection;
55  break;
56 
57  case Player::LEFT:
58  if (this->currentDirection != Player::RIGHT)
59  this->currentDirection = this->nextDirection;
60  break;
61 
62  case Player::UP:
63  if (this->currentDirection != Player::DOWN)
64  this->currentDirection = this->nextDirection;
65  break;
66 
67  case Player::DOWN:
68  if (this->currentDirection != Player::UP)
69  this->currentDirection = this->nextDirection;
70  break;
71  };
72 
73  // Making the rest of the body catch up
74  for (unsigned int i = (this->body.size() - 1); i > 0; i--)
75  {
76  this->body[i].x = this->body[i - 1].x;
77  this->body[i].y = this->body[i - 1].y;
78  }
79 
80  // Moving the head
81  switch(this->currentDirection)
82  {
83  case Player::RIGHT:
84  this->body.front().x++;
85  break;
86 
87  case Player::LEFT:
88  this->body.front().x--;
89  break;
90  case Player::UP:
91  this->body.front().y--;
92  break;
93 
94  case Player::DOWN:
95  this->body.front().y++;
96  break;
97  }
98 
99  // Checking if the player hit the board's extremes.
100  //
101  // @warning `teleport` may change player's X and Y!
102  if (board->isBorder(this->body.front().x,
103  this->body.front().y))
104  {
105  if (board->style == Board::TELEPORT)
106  board->teleport(this);
107  else
108  this->kill();
109  }
110 
111  int headx = this->body.front().x;
112  int heady = this->body.front().y;
113 
114  // Checking if the head hits the body
115  if (this->bodyHit(headx, heady, true))
116  this->kill();
117 
118  // Checking for collisions on the board
119  if (board->isWall(headx, heady))
120  this->kill();
121 }
122 void Player::draw(Window* win)
123 {
124  // The body
125  for (unsigned int i = 1; i < (this->body.size()); i++)
126  win->printChar('o',
127  this->body[i].x,
128  this->body[i].y,
129  Colors::pair(COLOR_GREEN, COLOR_DEFAULT, true));
130 
131  // The head
132  win->printChar(((this->alive) ?
133  '@' :
134  'X'),
135  this->body.front().x,
136  this->body.front().y,
137  Colors::pair(((this->alive) ?
138  COLOR_GREEN :
139  COLOR_RED), COLOR_DEFAULT, true));
140 }
141 bool Player::headHit(int x, int y)
142 {
143  return ((this->body.front().x == x) &&
144  (this->body.front().y == y));
145 }
146 bool Player::bodyHit(int x, int y, bool isCheckingHead)
147 {
148  int initial = 0;
149  if (isCheckingHead) initial = 3;
150 
151  for (unsigned int i = initial; i < (this->body.size()); i++)
152  if ((this->body[i].x == x) &&
153  (this->body[i].y == y))
154  return true;
155 
156  return false;
157 }
158 void Player::increase()
159 {
160  int lastx = this->body.back().x;
161  int lasty = this->body.back().y;
162 
163  this->body.push_back(Body(lastx, lasty));
164 }
165 
A segment of the terminal screen (2D char matrix).
Definition: Window.hpp:16
Definition: Player.hpp:8
Style style
Tells if the player will teleport when reaching the Board&#39;s limits or not.
Definition: Board.hpp:90
A level where the snake runs and eats fruits.
Definition: Board.hpp:32
bool isWall(int x, int y)
Tells if there&#39;s a wall at #x #y.
Definition: Board.cpp:36
void teleport(Player *player)
Makes the Player teleport if it&#39;s on a border.
Definition: Board.cpp:98
void printChar(int c, int x, int y, ColorPair pair=0)
Shows #c at #x #y with color #pair.
Definition: Window.cpp:105
int getX()
Returns the head&#39;s x position.
Definition: Player.cpp:25
bool bodyHit(int x, int y, bool isCheckingHead=false)
Tells if something at #x and #y collides with any part of the snake.
Definition: Player.cpp:146
int getY()
Returns the head&#39;s y position.
Definition: Player.cpp:29