Created
April 26, 2018 22:49
-
-
Save eXpl0it3r/fb17ef7fa3550ed0ad684342516a36a1 to your computer and use it in GitHub Desktop.
Sample Game
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
#include <SFML/Graphics.hpp> | |
#include <SFML/Audio.hpp> | |
#include "world.h" | |
int main() | |
{ | |
initializegame(); | |
generatecurrentlevel(levelnumber); | |
while(window.isOpen() && !sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) | |
{ | |
while(window.pollEvent(event)) | |
if(event.type == sf::Event::Closed) window.close(); | |
think(); | |
drawlevel(); | |
window.display(); | |
} | |
return 0; | |
} | |
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
#include <SFML/Graphics.hpp> | |
#include <SFML/Audio.hpp> | |
#include "windows.h" | |
#include "world.h" | |
#include <iostream> // Used to convert float to string for draw(text) | |
#include <sstream> // Used to convert float to string for draw(text) | |
#include <vector> | |
sf::RenderWindow window; | |
sf::Event event; | |
sf::Font font; | |
sf::Texture itemstexture; | |
sf::Sprite itemssprite[10]; | |
sf::Clock myclock; | |
sf::SoundBuffer soundbuffer_cardflip, soundbuffer_explosion, soundbuffer_win; | |
sf::Sound sound_cardflip, sound_explosion, sound_win; | |
int lives; | |
int levelnumber; | |
int flipsremaining; | |
int setsof; | |
int numberofbombs; | |
cardsshowing cardshown[2]; | |
int numberofcardsshowing; | |
levelstruct level[100][100]; | |
int levelwidth, levelheight; | |
int xoffset; | |
int yoffset; | |
int xspacing; | |
int yspacing; | |
bool leftmousedown, leftmousedownlastframe; | |
bool rightmousedown, rightmousedownlastframe; | |
void think() | |
{ | |
sf::Vector2i mousepos = sf::Mouse::getPosition(window); | |
int cardx, cardy; | |
if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) leftmousedown=true; | |
else leftmousedown=false; | |
if(sf::Mouse::isButtonPressed(sf::Mouse::Right)) rightmousedown=true; | |
else rightmousedown=false; | |
bool overcard=false; | |
if(mousepos.x>xoffset && mousepos.x<xspacing*(levelwidth-1)+64+xoffset) | |
if(mousepos.y>yoffset && mousepos.y<yspacing*(levelheight-1)+94+yoffset) | |
if((mousepos.x-xoffset)%xspacing<64 && (mousepos.y-yoffset)%yspacing<94) | |
{ | |
overcard=true; | |
cardx=(mousepos.x-xoffset)/xspacing; | |
cardy=(mousepos.y-yoffset)/yspacing; | |
} | |
// Set or clear flag | |
if(!rightmousedown && rightmousedownlastframe && overcard) | |
{ | |
level[cardy][cardx].flag=!level[cardy][cardx].flag; | |
} | |
// Clicked on a bomb OR ran out of flips | |
if(!leftmousedown && leftmousedownlastframe && overcard && level[cardy][cardx].bomb || flipsremaining<1) | |
{ | |
lives--; | |
if(lives<1) | |
{ | |
levelnumber=1; | |
lives=5; | |
} | |
generatecurrentlevel(levelnumber); | |
sound_explosion.play(); | |
} | |
// Flip card | |
// MUST use "else if" here or above code will reset board and this code will cause a click | |
else if(!leftmousedown && leftmousedownlastframe && overcard && numberofcardsshowing<2 && !level[cardy][cardx].matched && !level[cardy][cardx].bomb) | |
{ | |
level[cardy][cardx].cardfaceshowing=!level[cardy][cardx].cardfaceshowing; | |
if(level[cardy][cardx].cardfaceshowing) | |
{ | |
cardshown[numberofcardsshowing].x=cardx; | |
cardshown[numberofcardsshowing].y=cardy; | |
cardshown[numberofcardsshowing].showing=true; | |
numberofcardsshowing++; // We turned a card face up | |
if(numberofcardsshowing>1) // We have two cards up. Start the clock for a second until they both flip back automatically | |
{ | |
myclock.restart(); | |
} | |
flipsremaining--; | |
} | |
else numberofcardsshowing--; // We turned a card back face down | |
sound_cardflip.play(); | |
} | |
if(checkforwin()) | |
{ | |
levelnumber++; | |
generatecurrentlevel(levelnumber); | |
sound_win.play(); | |
} | |
// Check for match | |
if(numberofcardsshowing>1 && level[cardshown[0].y][cardshown[0].x].cardindex==level[cardshown[1].y][cardshown[1].x].cardindex) | |
{ | |
// MATCH!! | |
// Uncover all cards with the same number | |
int matchnumber=level[cardshown[0].y][cardshown[0].x].cardindex; | |
for(int j=0; j<levelheight; j++) | |
{ | |
for(int i=0; i<levelwidth; i++) | |
{ | |
if(level[j][i].cardindex==matchnumber) level[j][i].matched=true; | |
} | |
} | |
} | |
// Flip cards back if enough time passed | |
sf::Time elapsed = myclock.getElapsedTime(); | |
if(numberofcardsshowing>1 && elapsed.asMilliseconds()>400) | |
{ | |
level[cardshown[0].y][cardshown[0].x].cardfaceshowing=false; | |
level[cardshown[1].y][cardshown[1].x].cardfaceshowing=false; | |
cardshown[0].showing=false; | |
cardshown[1].showing=false; | |
numberofcardsshowing=0; | |
} | |
leftmousedownlastframe=leftmousedown; | |
rightmousedownlastframe=rightmousedown; | |
} | |
void drawlevel() | |
{ | |
std::stringstream buff; | |
int i, j; | |
window.clear(); | |
sf::Text text; | |
text.setFont(font); | |
text.setCharacterSize(36); | |
for(j=0; j<levelheight; j++) | |
{ | |
for(i=0; i<levelwidth; i++) | |
{ | |
if(level[j][i].cardfaceshowing && !level[j][i].matched) | |
{ | |
itemssprite[CARDUP].setPosition(i*xspacing+xoffset, j*yspacing+yoffset); | |
window.draw(itemssprite[CARDUP]); | |
} | |
else if(!level[j][i].matched) | |
{ | |
itemssprite[CARDDOWN].setPosition(i*xspacing+xoffset, j*yspacing+yoffset); | |
window.draw(itemssprite[CARDDOWN]); | |
} | |
if(level[j][i].bomb) | |
{ | |
itemssprite[BOMB].setPosition(i*xspacing+xoffset, j*yspacing+yoffset); | |
// window.draw(itemssprite[BOMB]); | |
} | |
if(level[j][i].flag) | |
{ | |
itemssprite[FLAG].setPosition(i*xspacing+xoffset, j*yspacing+yoffset); | |
window.draw(itemssprite[FLAG]); | |
} | |
// All this just to show card number on screen | |
text.setFillColor(sf::Color::Black); | |
buff.str(""); | |
buff<<level[j][i].cardindex; // Card matching number | |
text.setString(buff.str()); | |
if(level[j][i].cardindex<10) text.setPosition(i*xspacing+xoffset+26,j*yspacing+yoffset+22); | |
else text.setPosition(i*xspacing+xoffset+18,j*yspacing+yoffset+22); | |
// Show card number | |
if(level[j][i].cardfaceshowing && !level[j][i].matched) window.draw(text); | |
// Show surrounding bomb count | |
if(level[j][i].matched && !level[j][i].bomb) | |
{ | |
buff.str(""); | |
buff<<level[j][i].surroundingbombsamount; // Number of bombs around | |
text.setString(buff.str()); | |
text.setFillColor(sf::Color::White); | |
if(level[j][i].surroundingbombsamount<10) text.setPosition(i*xspacing+xoffset+26,j*yspacing+yoffset+22); | |
else text.setPosition(i*xspacing+xoffset+18,j*yspacing+yoffset+22); | |
window.draw(text); | |
} | |
} | |
} | |
text.setFillColor(sf::Color::White); | |
buff.str(""); | |
buff<<"Level: "<<levelnumber; | |
text.setString(buff.str()); | |
text.setPosition(1000,0); | |
window.draw(text); | |
text.setFillColor(sf::Color::White); | |
buff.str(""); | |
buff<<"Lives: "<<lives; | |
text.setString(buff.str()); | |
text.setPosition(1000,50); | |
window.draw(text); | |
text.setFillColor(sf::Color::White); | |
buff.str(""); | |
buff<<"Flips: "<<flipsremaining; | |
text.setString(buff.str()); | |
text.setPosition(1000,100); | |
window.draw(text); | |
text.setFillColor(sf::Color::White); | |
buff.str(""); | |
buff<<"Bombs: "<<numberofbombs; | |
text.setString(buff.str()); | |
text.setPosition(1000,150); | |
window.draw(text); | |
text.setFillColor(sf::Color::White); | |
buff.str(""); | |
buff<<"Sets of: "<<setsof; | |
text.setString(buff.str()); | |
text.setPosition(1000,200); | |
window.draw(text); | |
} | |
int countbombsat(int x, int y) | |
{ | |
int bombcount=0; | |
if(x>0) bombcount+=level[y][x-1].bomb; | |
if(x<levelwidth-1) bombcount+=level[y][x+1].bomb; | |
if(y>0) bombcount+=level[y-1][x].bomb; | |
if(y<levelheight-1) bombcount+=level[y+1][x].bomb; | |
if(x>0 && y>0) bombcount+=level[y-1][x-1].bomb; | |
if(x<levelwidth-1 && y>0) bombcount+=level[y-1][x+1].bomb; | |
if(x<levelwidth-1 && y<levelheight-1) bombcount+=level[y+1][x+1].bomb; | |
if(x>0 && y<levelheight-1) bombcount+=level[y+1][x-1].bomb; | |
return bombcount; | |
} | |
void generatecurrentlevel(int which) | |
{ | |
if(which==1) generatelevel(4, 4, 1, 4, 30); | |
else if(which==2) generatelevel(5, 5, 2, 4, 40); | |
else if(which==3) generatelevel(7, 5, 3, 3, 50); | |
else if(which==4) generatelevel(7, 6, 3, 3, 60); | |
else if(which==5) generatelevel(7, 6, 4, 3, 70); | |
else if(which==6) generatelevel(8, 6, 4, 3, 80); | |
else if(which==7) generatelevel(6, 5, 5, 3, 70); | |
else generatelevel(6, 6, 6, 3, 60); | |
} | |
void generatelevel(int width, int height, int numberofbombss, int setspertype, int nofflips) | |
{ | |
struct levelarrayindex { int x, y; }; | |
std::vector <levelarrayindex> lai(width*height); // A list of all array coordinates to help populate level array with bombs, cards, etc. | |
// Check to make sure we aren't requesting too many bombs | |
if(numberofbombss>width*height/3) | |
{ | |
MessageBoxA(NULL, "Too many bombs requested for level size", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
levelwidth=width; | |
levelheight=height; | |
setsof=setspertype; | |
flipsremaining=nofflips; | |
numberofbombs=numberofbombss; | |
xoffset=10; | |
yoffset=10; | |
xspacing=100; | |
yspacing=120; | |
// Reset everything | |
for(int j=0; j<levelheight; j++) | |
for(int i=0; i<levelwidth; i++) | |
{ | |
level[j][i].bomb=false; | |
level[j][i].bombrevealed=false; | |
level[j][i].cardfaceshowing=false; | |
level[j][i].cardindex=0; | |
level[j][i].flag=false; | |
level[j][i].matched=false; | |
level[j][i].surroundingbombsamount=0; | |
} | |
numberofcardsshowing=0; | |
cardshown[0].showing=false; | |
cardshown[1].showing=false; | |
// Set up vector coordinates | |
for(int j=0; j<height; j++) | |
{ | |
for(int i=0; i<width; i++) | |
{ | |
lai[j*width+i].x=i; | |
lai[j*width+i].y=j; | |
} | |
} | |
// Generate bombs | |
int bombcount=0; | |
while(bombcount<numberofbombss) | |
{ | |
int bombindex = rand() % lai.size(); | |
level[lai[bombindex].y][lai[bombindex].x].bomb=true; | |
// printf("%d, %d\n",lai[bombindex].x, lai[bombindex].y); | |
// printf("%d\n",level[lai[bombindex].y][lai[bombindex].x].bomb); | |
// printf("%d\n",lai.size()); | |
lai.erase(lai.begin() + bombindex); | |
bombcount++; | |
} | |
int numbertouse=1; | |
int numbersremaining=setspertype; // # of each number for cards | |
while(lai.size()>0) | |
{ | |
int numberindex = rand() % lai.size(); | |
level[lai[numberindex].y][lai[numberindex].x].cardindex=numbertouse; | |
lai.erase(lai.begin() + numberindex); | |
numbersremaining--; | |
if(numbersremaining<1) | |
{ | |
numbertouse++; | |
numbersremaining=4; | |
} | |
// If we only have 2 cards left, fill them up with the latest number | |
if(lai.size()<3) | |
{ | |
while(lai.size()>0) | |
{ | |
level[lai[0].y][lai[0].x].cardindex=numbertouse; | |
lai.erase(lai.begin()); | |
} | |
} | |
} | |
for(int j=0; j<levelheight; j++) | |
for(int i=0; i<levelwidth; i++) | |
level[j][i].surroundingbombsamount=countbombsat(i, j); | |
} | |
bool checkforwin() | |
{ | |
// Check here to make sure all bombs are either marked or revealed | |
int flippedcardscount=0; | |
for(int j=0; j<levelheight; j++) | |
for(int i=0; i<levelwidth; i++) | |
if(!level[j][i].bomb) flippedcardscount+=level[j][i].matched; | |
// printf("flipped cards: %d, number of bombs: %d, width*height: %d\n",flippedcardscount,numberofbombs,levelwidth*levelheight); | |
if(flippedcardscount+numberofbombs==levelwidth*levelheight) return true; | |
return false; | |
} | |
void initializegame() | |
{ | |
srand((unsigned int)time(NULL)); | |
window.create(sf::VideoMode(1240, 720), "MatchSweeper"); | |
if(!font.loadFromFile("forced square.ttf")) | |
{ | |
MessageBoxA(NULL, "Error loading font", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
if(!itemstexture.loadFromFile("graphics/items.png")) | |
{ | |
MessageBoxA(NULL, "Error loading items.png", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
if(!soundbuffer_cardflip.loadFromFile("sounds/flipcard.wav")) | |
{ | |
MessageBoxA(NULL, "Error loading flipcard.wav", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
sound_cardflip.setBuffer(soundbuffer_cardflip); | |
if(!soundbuffer_explosion.loadFromFile("sounds/explosion.wav")) | |
{ | |
MessageBoxA(NULL, "Error loading explosion.wav", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
sound_explosion.setBuffer(soundbuffer_explosion); | |
if(!soundbuffer_win.loadFromFile("sounds/win.wav")) | |
{ | |
MessageBoxA(NULL, "Error loading win.wav", "ERROR", MB_ICONERROR | MB_OK); | |
exit(1); | |
} | |
sound_win.setBuffer(soundbuffer_win); | |
itemssprite[0].setTexture(itemstexture); | |
itemssprite[0].setTextureRect(sf::IntRect(0, 0, 64, 128)); | |
itemssprite[1].setTexture(itemstexture); | |
itemssprite[1].setTextureRect(sf::IntRect(64, 0, 64, 128)); | |
itemssprite[2].setTexture(itemstexture); | |
itemssprite[2].setTextureRect(sf::IntRect(128, 0, 64, 128)); | |
itemssprite[3].setTexture(itemstexture); | |
itemssprite[3].setTextureRect(sf::IntRect(196, 0, 64, 128)); | |
lives=5; | |
levelnumber=1; | |
} |
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
#ifndef WORLD_H | |
#define WORLD_H | |
#include <SFML/Graphics.hpp> | |
#include <SFML/Audio.hpp> | |
#define CARDDOWN 0 | |
#define CARDUP 1 | |
#define FLAG 2 | |
#define BOMB 3 | |
extern sf::RenderWindow window; | |
extern sf::Event event; | |
extern sf::Font font; | |
extern sf::Texture itemstexture; | |
extern sf::Sprite itemssprite[10]; | |
extern sf::SoundBuffer soundbuffer_cardflip, soundbuffer_explosion, soundbuffer_win; | |
extern sf::Sound sound_cardflip, sound_explosion, sound_win; | |
struct cardsshowing | |
{ | |
bool showing; | |
int x, y; | |
}; | |
extern cardsshowing cardshown[2]; | |
extern int numberofcardsshowing; | |
extern sf::Clock myclock; // Used for pausing for a second while two cards are shown | |
struct levelstruct | |
{ | |
bool bomb; | |
// Bomb has to be either flagged or otherwise revealed to count | |
bool flag; | |
bool bombrevealed; | |
int surroundingbombsamount; | |
int cardindex; | |
bool cardfaceshowing; | |
bool matched; | |
}; | |
extern levelstruct level[100][100]; | |
extern int lives; | |
extern int levelnumber; | |
extern int flipsremaining; | |
extern int setsof; | |
extern int numberofbombs; | |
extern int levelwidth, levelheight; | |
extern int xoffset; | |
extern int yoffset; | |
extern int xspacing; | |
extern int yspacing; | |
void think(); | |
void initializegame(); | |
void generatelevel(int width, int height, int numberofbombss, int setspertype, int nofflips); | |
void generatecurrentlevel(int which); | |
void drawlevel(); | |
int countbombsat(int x, int y); | |
bool checkforwin(); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment