Skip to content

Commit 4f46c75

Browse files
Carlo Lanzi Lucianicarlolalu
Carlo Lanzi Luciani
authored andcommitted
Project 21.y - Game 'Puzzle 15'
1 parent 68f2491 commit 4f46c75

20 files changed

+612
-10
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ build
1111
**/*.out
1212
*/*.out
1313
.idea/
14+
./**/*.gch

LICENSE

+3-3
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ feature that (1) displays an appropriate copyright notice, and (2)
106106
tells the user that there is no warranty for the work (except to the
107107
extent that warranties are provided), that licensees may convey the
108108
work under this License, and how to view a copy of this License. If
109-
the interface presents a list of user commands or options, such as a
109+
the interface presents a list of user Commands or options, such as a
110110
menu, a prominent item in the list meets this criterion.
111111

112112
1. Source Code.
@@ -657,8 +657,8 @@ notice like this when it starts in an interactive mode:
657657
This is free software, and you are welcome to redistribute it
658658
under certain conditions; type `show c' for details.
659659

660-
The hypothetical commands `show w' and `show c' should show the appropriate
661-
parts of the General Public License. Of course, your program's commands
660+
The hypothetical Commands `show w' and `show c' should show the appropriate
661+
parts of the General Public License. Of course, your program's Commands
662662
might be different; for a GUI interface, you would use an "about box".
663663

664664
You should also get your employer (if you work as a programmer) or school,

learncpp.com-v09.2023/bookmark.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
topic 1: learncpp.com
2+
bookmark: 22.4
23

3-
21.y
4+
topic 2: learn smt about computer networks from 'a Top down approch'.
5+
Bookmark : ch1 - page18
46

5-
I add another topic here: learn smt about computer networks from the website of geeksforgeeks.
6-
topic 2: chapter Protocols
7+
topic 3: https://pages.github.com/ (personlise your github page to learn some html, css and javascript. Very not-necessary for now)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
cd src
4+
g++ -ggdb -pedantic-errors -Wall -Weffc++ -Wextra -Werror -Wsign-conversion -std=c++20 -o ../build/executable.out ./*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include"board.h"
2+
3+
void Board::randomMove()
4+
{
5+
this->move0(Direction::getRandom());
6+
}
7+
8+
void Board::randomise()
9+
{
10+
for(int index{}; index<100; ++index)
11+
{
12+
this->randomMove();
13+
}
14+
}
15+
16+
Point Board::getPosition(const Tile& tile) const
17+
{
18+
// bad practice, but not avoidable easily: we used `int` for the class Point, and not std::size_t
19+
int size { static_cast<int>(g_size) };
20+
// linear search because the board is not ordered and we used a C-array rather than a std::array
21+
for(int row_index{}; row_index < size; ++row_index)
22+
{
23+
for(int column_index{}; column_index< size; ++column_index)
24+
{
25+
if(m_grid[row_index][column_index]==tile){
26+
// note that we must invert the column and row index!
27+
// (matrix indices are inverted wrt cartesian coordinates)
28+
return {column_index, row_index};
29+
}
30+
}
31+
}
32+
return {-1,-1}; //will never happen
33+
}
34+
35+
Tile& Board::operator()(const Point& point)
36+
{
37+
// notice: we need to invert the indices between the cartesian and the matrix indexing
38+
return m_grid[point.getY()][point.getX()];
39+
}
40+
41+
Board& Board::move0(const Direction& direction)
42+
{
43+
Point zero_tile_position { this->getPosition(0) };
44+
Point adiacent_position { zero_tile_position.getAdjacentPoint(direction) };
45+
46+
if(adiacent_position.isOnBoard()){
47+
std::swap( this->operator()(zero_tile_position), this->operator()(adiacent_position));
48+
}
49+
50+
return *this;
51+
}
52+
53+
54+
std::ostream& operator<<(std::ostream& out, const Board& board)
55+
{
56+
for(int line{}; line < Konstants::g_consoleLines; ++line)
57+
{
58+
out << '\n';
59+
}
60+
61+
for(std::size_t index_r{}; index_r < g_size; ++index_r)
62+
{
63+
for(std::size_t index_c{}; index_c < g_size; ++index_c)
64+
{
65+
out << board.m_grid[index_r][index_c];
66+
}
67+
out << '\n';
68+
}
69+
return out;
70+
}
71+
72+
73+
bool operator==(const Board& board1, const Board& board2)
74+
{
75+
for(std::size_t index_r{}; index_r < g_size; ++index_r)
76+
{
77+
for(std::size_t index_c{}; index_c < g_size; ++index_c)
78+
{
79+
if( board1.m_grid[index_r][index_c] != board2.m_grid[index_r][index_c] ) {
80+
return false;
81+
}
82+
}
83+
}
84+
return true;
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef BOARD_H
2+
#define BOARD_H
3+
4+
#include <iostream>
5+
#include <algorithm>
6+
7+
#include "tile.h"
8+
#include "point.h" // which includes direction
9+
10+
#include "konstants.h"
11+
#include "random.h"
12+
13+
14+
class Board
15+
{
16+
public:
17+
Board() = default;
18+
19+
void randomMove();
20+
21+
void randomise();
22+
23+
// you can give an integer as an argument
24+
Point getPosition(const Tile& tile) const;
25+
26+
Tile& operator()(const Point& point);
27+
28+
Board& move0(const Direction& direction);
29+
30+
friend std::ostream& operator<<(std::ostream& out, const Board& board);
31+
32+
friend bool operator==(const Board& board1, const Board& board2);
33+
34+
private:
35+
Tile m_grid[g_size][g_size] {
36+
Tile{ 1 }, Tile { 2 }, Tile { 3 } , Tile { 4 },
37+
Tile { 5 } , Tile { 6 }, Tile { 7 }, Tile { 8 },
38+
Tile { 9 }, Tile { 10 }, Tile { 11 }, Tile { 12 },
39+
Tile { 13 }, Tile { 14 }, Tile { 15 }, Tile { 0 } };
40+
};
41+
42+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include"direction.h"
2+
3+
4+
Direction Direction::getRandom()
5+
{
6+
return Direction{Random::get<int>(0,3)};
7+
}
8+
9+
Direction::Possible Direction::getTowards() const
10+
{
11+
return m_towards;
12+
}
13+
14+
Direction Direction::operator-() const
15+
{
16+
if( m_towards <= 1 )
17+
{
18+
return Direction{ m_towards+2 };
19+
} else
20+
{
21+
return Direction{ m_towards-2 };
22+
}
23+
}
24+
25+
26+
std::ostream& operator<< (std::ostream& out, const Direction& direction)
27+
{
28+
switch(direction.getTowards())
29+
{
30+
case 0: out << Konstants::up; break;
31+
case 1: out << Konstants::right; break;
32+
case 2: out << Konstants::down; break;
33+
case 3: out << Konstants::left; break;
34+
default: out << "unknown direction"; break;
35+
}
36+
return out;
37+
}
38+
39+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef DIRECTION_H
2+
#define DIRECTION_H
3+
4+
#include<iostream>
5+
#include<assert.h>
6+
7+
#include "konstants.h"
8+
#include "random.h"
9+
10+
class Direction
11+
{
12+
public:
13+
enum Possible
14+
{
15+
up,
16+
right,
17+
down,
18+
left,
19+
20+
max_possible,
21+
};
22+
23+
static Direction getRandom();
24+
25+
Direction(Possible possible=up) : m_towards{ possible }
26+
{
27+
assert(possible>=0 && possible<=3 && "direction initialised with invalid number");
28+
}
29+
30+
Direction(int num=up) : Direction(static_cast<Direction::Possible>(num))
31+
{}
32+
33+
Possible getTowards() const;
34+
35+
Direction operator-() const;
36+
37+
friend std::ostream& operator<< (std::ostream& out, const Direction& direction);
38+
39+
private:
40+
Possible m_towards {up};
41+
};
42+
43+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef KONSTANTS_H
2+
#define KONSTANTS_H
3+
4+
namespace Konstants
5+
{
6+
constexpr int g_consoleLines{ 25 };
7+
8+
constexpr char unknown_input='0';
9+
constexpr char quit ='q';
10+
11+
constexpr char up='w';
12+
constexpr char right='d';
13+
constexpr char down='s';
14+
constexpr char left='a';
15+
}
16+
17+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
> Step #8
3+
4+
Goal: In this step, we’ll finish our game. Randomize the initial state of the game board. Also, detect when user wins, so after that we can print a win message and quit the game.
5+
6+
We need to be careful about how we randomize our puzzle, because not every puzzle is solvable. For example, there is no way to solve this puzzle:
7+
8+
1 2 3 4
9+
5 6 7 8
10+
9 10 11 12
11+
13 15 14
12+
13+
If we just blindly randomize the numbers in the puzzle, there is a chance that we will generate such an unsolvable puzzle. With a physical version of the puzzle, we’d randomize the puzzle by sliding tiles in random directions until the tiles were sufficiently mixed. The solution for such a randomized puzzle is to slide each tile in the opposite direction that it was slid to randomize it in the first place. Thus, randomizing puzzles this way always generates a solvable puzzle.
14+
15+
We can have our program randomize the board in the same way.
16+
17+
Once the user has solved the puzzle, the program should print "\n\nYou won!\n\n" and then exit normally.
18+
19+
*/
20+
21+
#include <iostream>
22+
#include "user_input.h"
23+
#include "board.h"
24+
25+
26+
int main()
27+
{
28+
std::cout << "Welcome to Puzzle 15!\n";
29+
30+
Board winning_board{};
31+
32+
Board board{};
33+
board.randomise();
34+
std::cout << board;
35+
36+
char ch{};
37+
38+
while(true)
39+
{
40+
std::cout << "\nGive me a direction with the commands '" << Konstants::up << "' '" << Konstants::right << "' '" << Konstants::down <<"' '" << Konstants::left << "' to move the empty tile around!\n";
41+
42+
ch = UserInput::getValidatedInput();
43+
44+
if(ch==Konstants::quit){
45+
std::cout << "\n\nBye!\n\n";
46+
return 0;
47+
}
48+
49+
board.move0(UserInput::validChar2direction(ch));
50+
std::cout << board << '\n';
51+
52+
if(board==winning_board)
53+
{
54+
std::cout << "Congratulations! You have won!";
55+
std::cout << "\n\nBye!\n\n";
56+
return 0;
57+
}
58+
}
59+
return 0;
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "point.h"
2+
3+
int Point::getX() const
4+
{
5+
return m_x;
6+
}
7+
8+
int Point::getY() const
9+
{
10+
return m_y;
11+
}
12+
13+
Point Point::getAdjacentPoint(const Direction& direction)
14+
{
15+
switch(direction.getTowards())
16+
{
17+
case 0: return Point{m_x, m_y-1};
18+
case 1: return Point{m_x+1, m_y};
19+
case 2: return Point{m_x, m_y+1};
20+
case 3: return Point{m_x-1, m_y};
21+
default: std::cout << "The given direction is invalid\n"; return *this;
22+
}
23+
}
24+
25+
bool Point::isOnBoard() const
26+
{
27+
int size { static_cast<int>(g_size) };
28+
return ( m_y>=0 && m_y<size && m_x>=0 && m_x<size );
29+
}
30+
31+
bool operator==(const Point& point1, const Point& point2)
32+
{
33+
return point1.m_x==point2.m_x && point1.m_y==point2.m_y;
34+
}
35+
36+
37+
bool operator!=(const Point& point1, const Point& point2)
38+
{
39+
return !(point1==point2);
40+
}
41+
42+
43+
std::ostream& operator<<(std::ostream& out, const Point& point)
44+
{
45+
out << "(" << point.getX() << "," << point.getY() << ")";
46+
return out;
47+
}
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+

0 commit comments

Comments
 (0)