Skip to content

Instantly share code, notes, and snippets.

@zekroTJA
Last active May 7, 2018 05:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zekroTJA/4f76ef1532bcc7a0155b7eddc7eb2ae1 to your computer and use it in GitHub Desktop.
Save zekroTJA/4f76ef1532bcc7a0155b7eddc7eb2ae1 to your computer and use it in GitHub Desktop.
Simple puzzle game created in school class
/*
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";
}
}
}
/*
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