Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: TicTacToe 2Players  (Read 7525 times)

0 Members and 1 Guest are viewing this topic.

dusan

  • Newbie
  • *
  • Posts: 12
    • View Profile
TicTacToe 2Players
« on: May 27, 2012, 03:51:54 pm »
My first project with SFML 2.0 I just wanted to make something simple to see how stuff works with SFML.
Done in in 3,5 hours.



Download link: http://www.2shared.com/file/JvIyLmij/TicTacToe.html
#include <SFML/Graphics.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Mouse.hpp>
#include <SFML/System/Sleep.hpp>
#include <SFML/Audio/SoundBuffer.hpp>
#include <SFML\Audio\Sound.hpp>
#include <iostream>
#include <sstream>
#include <string>
sf::Time thetime;
sf::Clock elapsed;
std::string IntToString(int d)
{
   std::stringstream ss;
   ss << d;
   return ss.str();
}

std::string GetFrameRate()
{    static int frameCounter = 0;
      static int fps = 0;
      frameCounter++;
      thetime = elapsed.getElapsedTime();
      if(thetime.asMilliseconds() > 999)
      {
         fps = frameCounter;
         frameCounter = 0;
         elapsed.restart();
      }

      return IntToString(fps);
}
const int SCREEN_WIDTH=649;
const int SCREEN_HEIGHT=460;
const int SCREEN_BPP=32;
sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP),"TicTacToe",!sf::Style::Resize|sf::Style::Close);
char *score[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"};
enum BoardValues{x,o,empty};
BoardValues board[3][3];
BoardValues onPlay;
BoardValues winnerCheck()
{
        if (board[0][0]==x && board[0][0]==board[1][1] && board[1][1]==board[2][2]) {return x;}
        if (board[2][0]==x && board[2][0]==board[1][1] && board[1][1]==board[0][2]) {return x;}
        if (board[0][0]==x && board[0][0]==board[1][0] && board[1][0]==board[2][0]) {return x;}
        if (board[0][1]==x && board[0][1]==board[1][1] && board[1][1]==board[2][1]) {return x;}
        if (board[0][2]==x && board[0][2]==board[1][2] && board[1][2]==board[2][2]) {return x;}
        if (board[0][0]==x && board[0][0]==board[0][1] && board[0][1]==board[0][2]) {return x;}
        if (board[1][0]==x && board[1][0]==board[1][1] && board[1][1]==board[1][2]) {return x;}
        if (board[2][0]==x && board[2][0]==board[2][1] && board[2][1]==board[2][2]) {return x;}
        if (board[0][0]==o && board[0][0]==board[1][1] && board[1][1]==board[2][2]) {return o;}
        if (board[2][0]==o && board[2][0]==board[1][1] && board[1][1]==board[0][2]) {return o;}
        if (board[0][0]==o && board[0][0]==board[1][0] && board[1][0]==board[2][0]) {return o;}
        if (board[0][1]==o && board[0][1]==board[1][1] && board[1][1]==board[2][1]) {return o;}
        if (board[0][2]==o && board[0][2]==board[1][2] && board[1][2]==board[2][2]) {return o;}
        if (board[0][0]==o && board[0][0]==board[0][1] && board[0][1]==board[0][2]) {return o;}
        if (board[1][0]==o && board[1][0]==board[1][1] && board[1][1]==board[1][2]) {return o;}
        if (board[2][0]==o && board[2][0]==board[2][1] && board[2][1]==board[2][2]) {return o;}
        return empty;
}
bool tie()
{
        for(int i=0;i<3;i++)
        {
                for(int j=0;j<3;j++)
                {
                        if (board[i][j]==empty)
                                return false;
                }
        }
        return true;
}
inline void pause()
{
                sf::Time forSleep;
                forSleep=sf::seconds(2.5f);
                sf::sleep(forSleep);
}
int main()
{
        int xScore=0,oScore=0,tieScore=0;
        sf::Text TtieScore(score[tieScore],sf::Font::getDefaultFont(),70);
        TtieScore.setColor(sf::Color::Black);
        TtieScore.setPosition(515,140);
        sf::Text TxScore(score[xScore],sf::Font::getDefaultFont(),70);
        TxScore.setColor(sf::Color(2,0,153));
        TxScore.setPosition(515,35);
        sf::Text ToScore(score[oScore],sf::Font::getDefaultFont(),70);
        ToScore.setColor(sf::Color(205,0,0));
        ToScore.setPosition(515,300);
        while(1)
        {
        for(int i=0;i<3;i++)
        {
                for(int j=0;j<3;j++)
                {
                        board[i][j]=empty;
                }
        }
        sf::Font font;
        if(!font.loadFromFile("ABITE.ttf"))
                return 1;
        sf::Text TxWin("X won",font,70);
        TxWin.setColor(sf::Color::Black);
        TxWin.setPosition(200,200);
        sf::Text ToWin("O won",font,70);
        ToWin.setColor(sf::Color::Black);
        ToWin.setPosition(200,200);
        sf::Text Ttie("Tie",font,70);
        Ttie.setColor(sf::Color::Black);
        Ttie.setPosition(200,200);
        sf::Text TtieText("Tie",font,25);
        TtieText.setColor(sf::Color::Black);
        TtieText.setPosition(450,132);
        sf::Text TplayerX("X Player",font,25);
        TplayerX.setColor(sf::Color (2,0,153));
        TplayerX.setPosition(450,25);
        sf::Text TplayerO("O Player",font,25);
        TplayerO.setColor(sf::Color(205,0,0));
        TplayerO.setPosition(450,290);
        window.setFramerateLimit(50);
        sf::SoundBuffer BXsound;
        if(!BXsound.loadFromFile("Xsound.wav"))
                return 1;
        sf::Sound Xsound;
        Xsound.setBuffer(BXsound);
        sf::SoundBuffer BOsound;
        if(!BOsound.loadFromFile("Osound.wav"))
                return 1;
        sf::Sound Osound;
        Osound.setBuffer(BOsound);
        sf::SoundBuffer BTieSound;
        if(!BTieSound.loadFromFile("TieSound.wav"))
                return 1;
        sf::Sound TieSound;
        TieSound.setBuffer(BTieSound);
        sf::Texture Tbackground;
    sf::Texture Tx;
    sf::Texture To;
        if(!Tbackground.loadFromFile("pozadina.jpg") || !Tx.loadFromFile("iks.jpg") || !To.loadFromFile("oks.jpg"))
                return 1;
        sf::Sprite Sbackground;
        sf::Sprite Sx;
        sf::Sprite So;
        Sx.setTexture(Tx);
        So.setTexture(To);
        Sbackground.setTexture(Tbackground);
        Sbackground.setPosition(0,0);
        sf::Sprite SonPlay;
        sf::Sprite Sfield[9];
        bool mouseClicked[9]={false,false,false,false,false,false,false,false,false};
        int turn=1;
        while(window.isOpen())
        {      
                window.setTitle("TicTacToe FPS:" + GetFrameRate());
                if(turn%2==0)
                {
                        SonPlay=So;
                        onPlay=o;
                }
                else
                {
                        SonPlay=Sx;
                        onPlay=x;
                }
                 sf::Event Event;
         while (window.pollEvent(Event))
         {
       
             if (Event.type == sf::Event::Closed)
                 window.close();
         }
                 //input
                 if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
                 {
                         sf::Vector2i mousePosition=sf::Mouse::getPosition(window);
                         if(mousePosition.x<125 && mousePosition.x>10 && mousePosition.y<130 && mousePosition.y>10 && mouseClicked[0]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[0]=true;
                                 Sfield[0]=SonPlay;
                                 Sfield[0].setPosition(10,10);
                                 turn++;
                                 board[0][0]=onPlay;

                         }//1,1 polje

                         if(mousePosition.x<280 && mousePosition.x>161 && mousePosition.y<130 && mousePosition.y>10 && mouseClicked[1]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[1]=true;
                                 Sfield[1]=SonPlay;
                                 Sfield[1].setPosition(161,10);
                                 turn++;
                                 board[0][1]=onPlay;
                         }//1,2 polje

                         if(mousePosition.x<414 && mousePosition.x>314 && mousePosition.y<130 && mousePosition.y>10 && mouseClicked[2]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[2]=true;
                                 Sfield[2]=SonPlay;
                                 Sfield[2].setPosition(314,10);
                                 turn++;
                                 board[0][2]=onPlay;
                         }//1,3 polje

                         if(mousePosition.x<125 && mousePosition.x>10 && mousePosition.y<291 && mousePosition.y>162 && mouseClicked[3]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[3]=true;
                                 Sfield[3]=SonPlay;
                                 Sfield[3].setPosition(10,161);
                                 turn++;
                                 board[1][0]=onPlay;
                         }//2,1 polje

                         if(mousePosition.x<280 && mousePosition.x>161 && mousePosition.y<291 && mousePosition.y>162 && mouseClicked[4]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[4]=true;
                                 Sfield[4]=SonPlay;
                                 Sfield[4].setPosition(161,170);
                                 turn++;
                                 board[1][1]=onPlay;
                         }//2,2 polje

                         if(mousePosition.x<414 && mousePosition.x>341 && mousePosition.y<291 && mousePosition.y>162 && mouseClicked[5]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[5]=true;
                                 Sfield[5]=SonPlay;
                                 Sfield[5].setPosition(319,166);
                                 turn++;
                                 board[1][2]=onPlay;
                         }//2,3 polje

                         if(mousePosition.x<125 && mousePosition.x>10 && mousePosition.y<438 && mousePosition.y>318 && mouseClicked[6]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[6]=true;
                                 Sfield[6]=SonPlay;
                                 Sfield[6].setPosition(10,322);
                                 turn++;
                                 board[2][0]=onPlay;
                         }//3,1 polje

                         if(mousePosition.x<280 && mousePosition.x>161 && mousePosition.y<438 && mousePosition.y>318 && mouseClicked[7]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[7]=true;
                                 Sfield[7]=SonPlay;
                                 Sfield[7].setPosition(161,322);
                                 turn++;
                                 board[2][1]=onPlay;
                         }//3,2 polje

                         if(mousePosition.x<414 && mousePosition.x>314 && mousePosition.y<438 && mousePosition.y>318 && mouseClicked[8]==false)
                         {
                                 if(onPlay==x)
                                         Xsound.play();
                                 else if (onPlay==o)
                                         Osound.play();
                                 mouseClicked[8]=true;
                                 Sfield[8]=SonPlay;
                                 Sfield[8].setPosition(314,322);
                                 turn++;
                                 board[2][2]=onPlay;
                         }//3,3 polje

                 }
                 window.clear(sf::Color(250,250,250));
                 if (winnerCheck()==x)
                 {
                         xScore++;
                         TxScore.setString(score[xScore]);
                         window.draw(TxWin);
                         window.display();
                         Xsound.play();
                         pause();
                         break;
                 }
                 else if(winnerCheck()==o)
                 {
                         oScore++;
                         ToScore.setString(score[oScore]);
                         window.draw(ToWin);
                         window.display();
                         Osound.play();
                         pause();
                         break;
                 }
                 else if (tie()==true)
                 {
                         tieScore++;
                         TtieScore.setString(score[tieScore]);
                         window.draw(Ttie);
                          window.display();
                          TieSound.play();
                         pause();
                         break;
                 }
                 window.draw(Sbackground);
                 for(int i=0;i<9;i++)
                         window.draw(Sfield[i]);
                 window.draw(TplayerX);
                 window.draw(TxScore);
                 window.draw(TplayerO);
                 window.draw(TtieScore);
                 window.draw(TtieText);
                 window.draw(ToScore);
                 window.display();
        }
        }
        return 0;
}
What do you think?
Am I doing something wrong?
If you have time check it out :)

PS.
Turn your speakers   :D

Rosme

  • Full Member
  • ***
  • Posts: 169
  • Proud member of the shoe club
    • View Profile
    • Code-Concept
Re: TicTacToe 2Players
« Reply #1 on: May 27, 2012, 10:53:45 pm »
Sounds are...interesting.
But you've distributed the debug version, you should have distributed the release one.
Also you forgot to give OpenAL32.dll and libsndfile-1.dll for the sound.
You also gave all dll, release and debug. The network dll is not use, so why giving it?
I didn't look much at the code, but why are you doing an infinite loop? It causes the game to never close when I close the game window. I have to close the console window myself, not something I expect.
I'll take a deeper look at the code later, and possibly post my thoughts on it(good and bad).
Other than that, the game still is clean and sweet.
GitHub
Code Concept
Twitter
Rosme on IRC/Discord

dusan

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: TicTacToe 2Players
« Reply #2 on: May 28, 2012, 05:48:58 pm »
Sounds are...interesting.
But you've distributed the debug version, you should have distributed the release one.
Also you forgot to give OpenAL32.dll and libsndfile-1.dll for the sound.
You also gave all dll, release and debug. The network dll is not use, so why giving it?
I didn't look much at the code, but why are you doing an infinite loop? It causes the game to never close when I close the game window. I have to close the console window myself, not something I expect.
I'll take a deeper look at the code later, and possibly post my thoughts on it(good and bad).
Other than that, the game still is clean and sweet.

Ty for your reply and comments.
I have never "release" game so it is kind new to me so ty for saying what I need to do next time.
Infinity loop is there to not allow game to close when 1 game is played-you can play as many games as you want, well 20 at the moment :).
I have fixed it adding goto: when sfml window is closed.
If you replay with thoughts about code I will be grateful to you.

Is this how it should look like :
http://www.2shared.com/file/0QXNhbSr/TicTacToe.html
« Last Edit: May 28, 2012, 06:08:36 pm by dusan »

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: TicTacToe 2Players
« Reply #3 on: May 28, 2012, 07:13:43 pm »
I have fixed it adding goto: when sfml window is closed.

Oh god, this would take some explaining... Let's just put it this way, goto bad. Especially if you're a new programmer.

It's something you should just condition yourself to avoid by impulse and be done with. There was a lengthy debate about the pros and cons about thirty years ago, the general consensus was "no unless you're being really clever" and it's faded from modern usage almost entirely (with most modern languages not even featuring a goto command).
« Last Edit: May 28, 2012, 07:22:24 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Rosme

  • Full Member
  • ***
  • Posts: 169
  • Proud member of the shoe club
    • View Profile
    • Code-Concept
Re: TicTacToe 2Players
« Reply #4 on: May 28, 2012, 10:31:00 pm »
The problem with goto, is generally no respect for SESE and such things.
I'll change what MorleyDev said. It's not bad. It's EVIL when you begin.

Now for your code:
You mind explaining the way you did your include? Only SFML/Graphics.hpp and SFML/Audio.hpp are needed, since Graphics include all the other.

Globals are almost as evil as goto. What you did is C using C++ syntax. You could, and should, try to englobe the game into a class. The only global in this case that could be ok, are the const int for the size. Plus except board[][](and possibly your clock, that can be fixed with what I say after), there is not an object you use in the other functions. And if you ever needed them, you would have passed them by references.

The way you calculate the framerate is not the best(not even sure it's really precise).
You could just go with something like that:
return IntToString(static_cast<int>(1.f/elapsed.restart().asSeconds()));
I'll be picky here, but you could just use std::ostringstream. It indicates that it's only that way you'll be using, also a bit faster(but it's optional, just me going crazy with those little thing).

Your pause function is useless. You could just do:
sf::sleep(sf::Seconds(2.5f));

You still have your infinite loop and you "solved" the problem with a goto. Don't. The game loop you need is already there with window.isOpen(). Remove the while(1) and the goto.

The way you handle mouse click looks good though.

You should  consider spacing out your code and commenting more. Even if you don't intend to show your code. It's always usefull to see why you did thing and the reason for some code. Later, when you'll look back at your code, you will find those comments very usefull.

Last thing. I find that the code looks very much beginner. Not that it's bad. We all started somewhere and produced bad code, and we pretty much all do it from times to times(or is it just me?). But you should consider practicing your C++ before going into games. Things like Class, standard containers(std::array, std::vector), templates could help you.
GitHub
Code Concept
Twitter
Rosme on IRC/Discord

dusan

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: TicTacToe 2Players
« Reply #5 on: May 29, 2012, 03:40:28 pm »
I have fixed it adding goto: when sfml window is closed.

Oh god, this would take some explaining... Let's just put it this way, goto bad. Especially if you're a new programmer.

It's something you should just condition yourself to avoid by impulse and be done with. There was a lengthy debate about the pros and cons about thirty years ago, the general consensus was "no unless you're being really clever" and it's faded from modern usage almost entirely (with most modern languages not even featuring a goto command).
I used goto because there is 3 while loops in there and no other way of exiting 3 of them at once since break just brakes one while. If you know some other solutions of exiting 3 while (or for) loops at once share please I had similar problems before.
The problem with goto, is generally no respect for SESE and such things.
I'll change what MorleyDev said. It's not bad. It's EVIL when you begin.

Now for your code:
You mind explaining the way you did your include? Only SFML/Graphics.hpp and SFML/Audio.hpp are needed, since Graphics include all the other.

Globals are almost as evil as goto. What you did is C using C++ syntax. You could, and should, try to englobe the game into a class. The only global in this case that could be ok, are the const int for the size. Plus except board[][](and possibly your clock, that can be fixed with what I say after), there is not an object you use in the other functions. And if you ever needed them, you would have passed them by references.

The way you calculate the framerate is not the best(not even sure it's really precise).
You could just go with something like that:
return IntToString(static_cast<int>(1.f/elapsed.restart().asSeconds()));
I'll be picky here, but you could just use std::ostringstream. It indicates that it's only that way you'll be using, also a bit faster(but it's optional, just me going crazy with those little thing).

Your pause function is useless. You could just do:
sf::sleep(sf::Seconds(2.5f));

You still have your infinite loop and you "solved" the problem with a goto. Don't. The game loop you need is already there with window.isOpen(). Remove the while(1) and the goto.

The way you handle mouse click looks good though.

You should  consider spacing out your code and commenting more. Even if you don't intend to show your code. It's always usefull to see why you did thing and the reason for some code. Later, when you'll look back at your code, you will find those comments very usefull.

Last thing. I find that the code looks very much beginner. Not that it's bad. We all started somewhere and produced bad code, and we pretty much all do it from times to times(or is it just me?). But you should consider practicing your C++ before going into games. Things like Class, standard containers(std::array, std::vector), templates could help you.

I dont know why but strange thinks happened to me after I installed SFML to my computer. Creating debug and release libraries went fine, linking them also went fine but when I tried to compile some simple code I was unable because that code contained sf::Event class and editor was unable to find that class. (I included SFML/Graphics). I have used google for few days, posted problem here-noting helped. And than one day I got idea to do :
#include <SFML/Window/Event.hpp>
and it helped, since than I have to do it all like this.
You are right about globals but as I wrote it is my first app with sfml and I didnt write it to be clean just to see how classes in sfml works, so I wasnt paying any attention to it.
My goal wasnt to make a game - it was just to see how things work so I didnt use any classes.
I had some problems with sf::sleep coulnt make it to work so I put it like this but now I see how it is done :D
If I remove infinity while it wouldnt be able to play more games because  1 game (board gets full,score is counted) is in window.isOpen() and while(1) repeats that action. So instead of playing one game and exit application and enter again you can do it like this.
Idea about commenting code is good but I did int in few hours (I knew i wont leave it for tomorrow) and had all that stuff in my head and too lazy to comment :) .
I know a lot about c++ because I have learning it in school for 1 year now. We did OOP, STL and templates but I repeat again my goal wasnt to create a game, it was just to see how stuff in SFML works.
Ty for your replays it was useful.

Rosme

  • Full Member
  • ***
  • Posts: 169
  • Proud member of the shoe club
    • View Profile
    • Code-Concept
Re: TicTacToe 2Players
« Reply #6 on: May 29, 2012, 04:56:23 pm »
No problem. I was just saying what I thought about it.
But in my opinion, even if it's just to test, you should make the correct things. The fact you have a while(1) and globals are design flaw. I know you said it was just to try out sfml classes, but good practice should always be used, even if for small test like this.

As for your problem with building and headers, I suggest you re-install your sfml. I don't see any reason to build it yourself, since it's given pre-build on the download(unless you use VS2005, in which case I'd suggest to move to a newer version).
GitHub
Code Concept
Twitter
Rosme on IRC/Discord