Last active
May 7, 2018 05:50
-
-
Save zekroTJA/4f76ef1532bcc7a0155b7eddc7eb2ae1 to your computer and use it in GitHub Desktop.
Simple puzzle game created in school class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Simple Puzzle Game v.1.8.2 | |
© 2018 Ringo Hoffmann | |
Start Arguments: | |
-r Reset high score | |
-d Enable debug mode | |
*/ | |
// Check if code is compiling on Windows. | |
// Then define WIN flag | |
#if defined(_WIN32) || defined(_WIN64) | |
#define WIN | |
#endif | |
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <algorithm> | |
#include <math.h> | |
#include <time.h> | |
#include <sstream> | |
// conio is an old DOS-Lib only natively | |
// available on Windows | |
#ifdef WIN | |
#include <conio.h> | |
#endif | |
using namespace std; | |
#define VERSION "1.8.2" | |
#define HS_FILENAME "highscore.dat" | |
enum KEY { | |
KEY_UP = 72, | |
KEY_DOWN = 80, | |
KEY_LEFT = 75, | |
KEY_RIGHT = 77 | |
}; | |
struct HighScore { | |
int m, t; | |
}; | |
// moves counter | |
int moves = 0, debug_mode = 0, seed = 0; | |
HighScore highscore; | |
// Initializing 2-dimensional field | |
int f[3][3]; | |
// clear display help function | |
void cls() { | |
#ifdef WIN | |
system("cls"); | |
#else | |
system("clear"); | |
#endif | |
} | |
string get_time_diff(int timediff) { | |
stringstream ss; | |
ss << (timediff / 60) << " min, " << (timediff % 60) << " sec"; | |
return ss.str(); | |
} | |
// printing field with moves count | |
void print_field() { | |
cls(); | |
if (debug_mode) | |
cout << "DEBUG MODE ENABLED\n\n"; | |
cout << "Puzzle Game by Ringo Hoffmann\n© 2018\n" | |
<< "v." << VERSION << "\n\n" | |
<< "[Start with argument '-r' to reset highscore.]\n\n" | |
<< "Seed: " << seed << "\n" | |
<< "Move: " << moves + 1 << "\n" | |
<< "Highscore: "; | |
if (highscore.m == -1) | |
cout << "not set yet\n\n"; | |
else | |
cout << "\n - Moves: " << highscore.m | |
<< "\n - Time: " << get_time_diff(highscore.t) | |
<< "\n\n"; | |
cout << " +-------+\n"; | |
for (int i = 0; i < 3; i++) { | |
cout << " | "; | |
for (int j = 0; j < 3; j++) { | |
if (f[i][j] == 0) | |
cout << " "; | |
else | |
cout << f[i][j] << " "; | |
} | |
cout << "|\n"; | |
} | |
cout << " +-------+\n"; | |
} | |
// get position of number in field | |
void get_pos(int n, int *pos) { | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
if (f[i][j] == n) { | |
pos[0] = i; | |
pos[1] = j; | |
return; | |
} | |
} | |
} | |
} | |
// check if finish sequenze is reached | |
bool is_finished() { | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
int pos = 3 * i + j + 1; | |
if (pos < 9 && f[i][j] != pos || f[2][2] != 0) | |
return false; | |
} | |
} | |
return true; | |
} | |
// getting highscore from file | |
// if file is not existent, it returns -1 | |
// (= not set) | |
HighScore get_highscore() { | |
ifstream fr(HS_FILENAME); | |
HighScore out; | |
if (fr.good()) { | |
fr >> out.m; | |
fr >> out.t; | |
} | |
return out; | |
} | |
// write highscore to file | |
void set_highscore(HighScore hs) { | |
ofstream fw(HS_FILENAME); | |
if (fw.good()) { | |
fw << hs.m << endl << hs.t; | |
fw.close(); | |
} | |
} | |
// reset highscore by writing -1 | |
// (= not set) to the high score file | |
void reset_highscore() { | |
HighScore hs = { -1, -1 }; | |
set_highscore(hs); | |
} | |
// just a function to check if an argument is | |
// set as start argument | |
// More information about this here: | |
// https://zekro.de/gist/cppargs | |
bool arg_exists(char** begin, char** end, const string& option) { | |
return find(begin, end, option) != end; | |
} | |
// Get seed by manual input or randomly by timestamp | |
// if jumped input with '0' input | |
int get_seed() { | |
int seed; | |
if (!debug_mode) { | |
cout << "Puzzle Game by Ringo Hoffmann\n© 2018\n" | |
<< "v." << VERSION << "\n\n" | |
<< "Enter a seed (Enter 0 to use time generated seed) > "; | |
cin >> seed; | |
} | |
if (!cin || seed == 0) { | |
cin.clear(); | |
return time(NULL); | |
} | |
return seed; | |
} | |
int main(int argc, char* argv[]) { | |
// checking for debug and reset start argument | |
if (arg_exists(argv, argv + argc, "-d")) | |
debug_mode = 1; | |
if (arg_exists(argv, argv + argc, "-r")) | |
reset_highscore(); | |
// get highscore | |
highscore = get_highscore(); | |
int i = 0; | |
seed = get_seed(); | |
// filling field with numbers randomly | |
// if debug_mode is set, it will be filled | |
// with a prepared structure which can be solved | |
// with only one move | |
if (!debug_mode) { | |
srand(seed); | |
while (i < 9) { | |
int numbs[] = { 1,2,3,4,5,6,7,8,0 }; | |
int c_r[] = { rand() % 3, rand() % 3 }; | |
int *e = &f[c_r[0]][c_r[1]]; | |
if (*e == 0) { | |
*e = numbs[i++]; | |
} | |
} | |
} | |
else { | |
int count = 1; | |
for (int i = 0; i < 2; i++) | |
for (int j = 0; j < 3; j++) | |
f[i][j] = count++; | |
f[2][0] = 7; | |
f[2][1] = 0; | |
f[2][2] = 8; | |
} | |
int start_time = time(NULL); | |
int inpt; | |
do { | |
print_field(); | |
#ifdef WIN | |
/* | |
Using arrow keys to move | |
numbers. Because of conio include | |
only available compiled on windows. | |
*/ | |
cout << "\n[Use arrow keys to move numbers]"; | |
inpt = getch(); | |
int pos[2], free[2]; | |
get_pos(0, free); | |
switch (inpt) { | |
case KEY_DOWN: | |
if (free[0] == 0) | |
continue; | |
pos[0] = free[0] - 1; | |
pos[1] = free[1]; | |
break; | |
case KEY_UP: | |
if (free[0] == 2) | |
continue; | |
pos[0] = free[0] + 1; | |
pos[1] = free[1]; | |
break; | |
case KEY_RIGHT: | |
if (free[1] == 0) | |
continue; | |
pos[0] = free[0]; | |
pos[1] = free[1] - 1; | |
break; | |
case KEY_LEFT: | |
if (free[1] == 2) | |
continue; | |
pos[0] = free[0]; | |
pos[1] = free[1] + 1; | |
break; | |
default: | |
continue; | |
} | |
#else | |
/* | |
If compiled on linux, use "old" | |
system getting number to move by | |
input numer. | |
*/ | |
cout << "\nEnter number (0 for exit) > "; | |
cin >> inpt; | |
// check if input is in bounds | |
// else: ignore input | |
if (inpt > 8 || inpt < 0) | |
continue; | |
int pos[2], free[2]; | |
// get grid position of input number | |
// and free slot (0) | |
get_pos(inpt, pos); | |
get_pos(0, free); | |
// calculate difference between the two points | |
float diff = sqrt( | |
(free[0] - pos[0]) * (free[0] - pos[0]) + | |
(free[1] - pos[1]) * (free[1] - pos[1]) | |
); | |
// If the difference is more than 1, | |
// ignore input | |
if (diff > 1) | |
continue; | |
#endif | |
// swap value of input position with | |
// value of empty (0) position and | |
// count up moves after | |
f[free[0]][free[1]] = f[pos[0]][pos[1]]; | |
f[pos[0]][pos[1]] = 0; | |
moves++; | |
} | |
// cancel with input 0 or if finished | |
while (inpt != 0 && !is_finished()); | |
print_field(); | |
int time_diff = time(NULL) - start_time; | |
// just a check to dont print won text if | |
// canceled with 0-input | |
// else print won text, moves and save as | |
// high score, if moves are less then the set | |
// high score or if high score was not set before | |
if (inpt != 0) { | |
cout << "\nWon!\nCount of moves: " << moves << endl; | |
cout << "Time needed: " << get_time_diff(time_diff) << endl; | |
if (time_diff < highscore.t || highscore.t == -1) { | |
HighScore hs = { moves, time_diff }; | |
set_highscore(hs); | |
cout << "Congratulation! You set a new highscore!\n"; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Simple Puzzle Game | |
Simple Version | |
© 2018 Ringo Hoffmann | |
*/ | |
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <algorithm> | |
#include <math.h> | |
#include <time.h> | |
using namespace std; | |
void pause() { | |
char a; | |
cin >> a; | |
} | |
// moves counter | |
int moves = 0; | |
// Initializing 2-dimensional field | |
int f[3][3]; | |
// clear display help function | |
void cls() { | |
#if defined(_WIN32) || defined(_WIN64) | |
system("cls"); | |
#else | |
system("clear"); | |
#endif | |
} | |
// printing field with moves count | |
void print_field() { | |
cls(); | |
cout << "Moves: " << moves << "\n\n"; | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
if (f[i][j] == 0) | |
cout << " "; | |
else | |
cout << f[i][j] << " "; | |
} | |
cout << "\n"; | |
} | |
} | |
// get position of number in field | |
void get_pos(int n, int *pos) { | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
if (f[i][j] == n) { | |
pos[0] = i; | |
pos[1] = j; | |
return; | |
} | |
} | |
} | |
} | |
// check if finish sequenze is reached | |
bool is_finished() { | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
int pos = 3 * i + j + 1; | |
if (pos < 9 && f[i][j] != pos || f[2][2] != 0) | |
return false; | |
} | |
} | |
return true; | |
} | |
int main(int argc, char *argv[]) { | |
int i = 0; | |
srand(time(NULL)); | |
while (i < 9) { | |
int numbs[] = { 1,2,3,4,5,6,7,8,0 }; | |
int c_r[] = { rand() % 3, rand() % 3 }; | |
int *e = &f[c_r[0]][c_r[1]]; | |
if (*e == 0) { | |
*e = numbs[i++]; | |
} | |
} | |
int inpt; | |
do { | |
print_field(); | |
cout << "\nEnter number (0 for exit) > "; | |
cin >> inpt; | |
// check if input is in bounds | |
// else: ignore input | |
if (inpt > 8 || inpt < 0) | |
continue; | |
int pos[2], free[2]; | |
// get grid position of input number | |
// and free slot (0) | |
get_pos(inpt, pos); | |
get_pos(0, free); | |
// calculate difference between the two points | |
float diff = sqrt( | |
(free[0] - pos[0]) * (free[0] - pos[0]) + | |
(free[1] - pos[1]) * (free[1] - pos[1]) | |
); | |
// If the difference is more than 1, | |
// ignore input | |
if (diff > 1) | |
continue; | |
// swap value of input position with | |
// value of empty (0) position and | |
// count up moves after | |
int tmp = f[pos[0]][pos[1]]; | |
f[free[0]][free[1]] = f[pos[0]][pos[1]]; | |
f[pos[0]][pos[1]] = 0; | |
moves++; | |
} | |
// cancel with input 0 or if finished | |
while (inpt != 0 && !is_finished()); | |
print_field(); | |
// just a check to dont print won text if | |
// canceled with 0-input | |
// else print won text and moves | |
if (inpt != 0) | |
cout << "\nWon!\nCount of moves: " << moves << endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment