Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SFML/Graphics.hpp>
- #include <SFML/Window.hpp>
- #include <SFML/System.hpp>
- #include <vector>
- #include <iostream>
- #define WIDTH 6
- #define HEIGHT 10
- #define SIZE 25
- sf::Color colors[5] = { sf::Color::Red, sf::Color::Green, sf::Color::Blue, sf::Color::Magenta, sf::Color::Yellow };
- void drawQuad(sf::RenderTarget & rt, float x, float y, sf::Color c)
- {
- sf::RectangleShape rect(sf::Vector2f(SIZE-2, SIZE-2));
- rect.setPosition(x+1, y+1);
- rect.setFillColor(c);
- rt.draw(rect);
- }
- class Part
- {
- public:
- int m_x, m_y;
- char m_data[2][2];
- void generateData()
- {
- m_x = WIDTH / 2 - 1;
- m_y = -1;
- m_data[0][0] = rand() % 5;
- for(int i=0;i<100;i++) rand();
- m_data[0][1] = rand() % 5;
- m_data[1][0] = m_data[1][1] = -1;
- }
- Part()
- {
- generateData();
- }
- void rotate()
- {
- char c = m_data[0][0];
- m_data[0][0] = m_data[1][0];
- m_data[1][0] = m_data[1][1];
- m_data[1][1] = m_data[0][1];
- m_data[0][1] = c;
- if(m_data[0][0] == -1)
- {
- m_data[0][0] = m_data[0][1];
- m_data[1][0] = m_data[1][1];
- m_data[0][1] = m_data[1][1] = -1;
- }
- }
- void render(sf::RenderTarget & rt)
- {
- for(int i=0;i<2;i++)
- for(int j=0;j<2;j++)
- if(m_data[i][j] != -1)
- drawQuad(rt, (m_x + j) * SIZE, (m_y + i) * SIZE, colors[m_data[i][j]]);
- }
- void fall()
- {
- m_y++;
- }
- bool isWithinRange(int offsetX, int offsetY)
- {
- for(int i=0;i<2;i++)
- for(int j=0;j<2;j++)
- if(m_data[i][j] != -1 && (m_x + j + offsetX >= WIDTH || m_y + i + offsetY >= HEIGHT ||
- m_x + j + offsetX < 0 || m_y + i + offsetY < 0) )
- return false;
- return true;
- }
- };
- class Well
- {
- private:
- char m_data[HEIGHT][WIDTH];
- bool checkedData[HEIGHT][WIDTH];
- public:
- void clearArea()
- {
- for(int i=0;i<HEIGHT;i++)
- for(int j=0;j<WIDTH;j++)
- m_data[i][j] = -1;
- }
- Well()
- {
- clearArea();
- }
- void render(sf::RenderTarget & rt)
- {
- for(int i=0;i<HEIGHT;i++)
- for(int j=0;j<WIDTH;j++)
- if(m_data[i][j] != -1)
- drawQuad(rt, j * SIZE, i * SIZE, colors[m_data[i][j]]);
- }
- void addPart(Part p)
- {
- for(int i=0;i<2;i++)
- for(int j=0;j<2;j++)
- if(p.m_data[i][j] != -1)
- m_data[p.m_y + i][p.m_x + j] = p.m_data[i][j];
- }
- bool collideWithPart(Part p)
- {
- for(int i=0;i<2;i++)
- for(int j=0;j<2;j++)
- if(m_data[p.m_y + i][p.m_x + j] != -1 && p.m_data[i][j] != -1)
- return true;
- return false;
- }
- void applyGravity()
- {
- for(int k=0;k<HEIGHT;k++)
- for(int i=HEIGHT-1;i>1;i--)
- for(int j=0;j<WIDTH;j++)
- if(m_data[i][j] == -1)
- {
- m_data[i][j] = m_data[i-1][j];
- m_data[i-1][j] = -1;
- }
- }
- int dfs(int x, int y, int k, bool canChange)
- {
- int dx[] = {1,-1,0,0};
- int dy[] = {0,0,1,-1};
- if(canChange) m_data[y][x] = -1;
- checkedData[y][x] = true;
- int res = 0;
- for(int i=0;i<4;i++)
- {
- int xx = x + dx[i], yy = y + dy[i];
- if(xx < 0 || xx >= WIDTH || yy < 0 || yy >= HEIGHT || m_data[yy][xx] != k || checkedData[yy][xx]) continue;
- res += dfs(xx, yy, k, canChange);
- }
- return 1 + res;
- }
- void resetChecked()
- {
- for(int i=0;i<HEIGHT;i++)
- for(int j=0;j<WIDTH;j++)
- checkedData[i][j] = false;
- }
- int destroyComponents()
- {
- int res = 0;
- resetChecked();
- for(int i=0;i<HEIGHT;i++)
- for(int j=0;j<WIDTH;j++)
- if(m_data[i][j] != -1)
- if(dfs(j, i, m_data[i][j], false) > 3)
- {
- resetChecked();
- dfs(j, i, m_data[i][j], true);
- if(res == 0) res = 1;
- else res *= 2;
- }
- applyGravity();
- return res;
- }
- };
- int main()
- {
- srand(time(0));
- sf::RenderWindow window(sf::VideoMode(WIDTH * SIZE, HEIGHT * SIZE), "Quadrapop");
- window.setFramerateLimit(30);
- Part part;
- Well well;
- int tick = 0, score = 0;
- while(window.isOpen())
- {
- sf::Event event;
- while(window.pollEvent(event))
- {
- if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
- window.close();
- if(event.type == sf::Event::Closed)
- window.close();
- if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Right && part.isWithinRange(1,0))
- {
- part.m_x++;
- if(well.collideWithPart(part))
- part.m_x--;
- }
- if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Left && part.isWithinRange(-1,0))
- {
- part.m_x--;
- if(well.collideWithPart(part))
- part.m_x++;
- }
- if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Down)
- {
- while(1)
- {
- part.m_y++;
- if(part.isWithinRange(0,1) == false || well.collideWithPart(part))
- {
- part.m_y--;
- well.addPart(part);
- well.applyGravity();
- part.generateData();
- break;
- }
- }
- }
- if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Up)
- {
- part.rotate();
- if(well.collideWithPart(part) || part.isWithinRange(0,0) == false)
- for(int i=0;i<3;i++)
- part.rotate();
- }
- }
- if(tick < 20)
- tick++;
- else
- part.fall(), tick = 0;
- if(well.collideWithPart(part) || part.isWithinRange(0,1) == false)
- {
- part.m_y--;
- if(part.m_y == -1)
- {
- // koniec
- break;
- }
- well.addPart(part);
- well.applyGravity();
- part.generateData();
- }
- score += well.destroyComponents();
- window.clear();
- part.render(window);
- well.render(window);
- window.display();
- std::cout<<"Current score: "<<score<<std::endl;
- }
- std::cout<<"Final score: "<<score<<std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement