91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++如何實現俄羅斯方塊

發布時間:2020-07-21 17:29:32 來源:億速云 閱讀:179 作者:小豬 欄目:開發技術

這篇文章主要講解了C++如何實現俄羅斯方塊,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。

本文實例為大家分享了C++實現俄羅斯方塊的具體代碼,供大家參考,具體內容如下

主程序

RussiaBlock.cpp

//
// Created by adl on 2020/7/18.
//
#include "Block.h"
#include "Table.h"
#include <thread>
#include <mutex>
#include "hierarchical_mutex.h"
#include "fstream"

using namespace std;
thread_local uint64_t
  hierarchical_mutex::this_thread_hierarchical_value = ULONG_MAX;

int main(int argc, char **argv) {
 int level = 1;
 if (argc == 2) {
  if ((level = atoi(argv[1])) == 0) {
   cerr << "./a.out number " << endl;
   exit(-1);
  }

 }
 static int flag = 1;//全局變量
 static Table tab(20, 20, level); //構造一個15,20的棋盤
 static Block bl;  //構造一個落下方塊
 hierarchical_mutex table_mtx(2);
 hierarchical_mutex mtx(1);


 thread getkey([&]() {
  unsigned char buf[2];
  struct termios saveterm, nt;
  fd_set rfds, rs;
  struct timeval tv;
  int i = 0, q, r, fd = 0;//標準輸入
  tcgetattr(fd, &saveterm);
  nt = saveterm;
  nt.c_lflag &= ~ECHO;
  nt.c_lflag &= ~ISIG;
  nt.c_lflag &= ~ICANON;
  tcsetattr(fd, TCSANOW, &nt);
  FD_ZERO(&rs);
  FD_SET(fd, &rs);
  tv.tv_usec = 0;
  tv.tv_sec = 0;
  while (1) {
   read(0, buf, 1);
   buf[1] = '\0';
   r = select(fd + 1, &rfds, nullptr, nullptr, &tv);
   if (r < 0) {
    write(fileno(stderr), "select error.\n", sizeof("select error.\n"));
   }
   rfds = rs;
   std::unique_lock<hierarchical_mutex> table_lock(table_mtx);
   //上下左右
   switch (buf[0]) {
    case 'A': {
     //旋轉
     tab.clr_block(bl);//
     if (bl.get_type() == 5)continue;
     bl.rotate();
     if (tab.set_block(bl) == -1) {
      bl.rotate_back();
      tab.set_block(bl);
      continue;
     }
     break;
    }
    case 'B': {
     //向下(加速)
     tab.clr_block(bl);
     bl.move(Block::DOWN);
     if (tab.set_block(bl) == -1) {
      bl.move(Block::UP);
      tab.set_block(bl);
     }
     break;
    }
    case 'C': {
     /*向右*/
     tab.clr_block(bl);
     bl.move(Block::RIGHT);
     if (tab.set_block(bl) == -1) {
      bl.move(Block::LEFT);
      tab.set_block(bl);
     }
     break;
    }
    case 'D': {
     //左
     tab.clr_block(bl);
     bl.move(Block::LEFT);
     if (tab.set_block(bl) == -1) {
      bl.move(Block::RIGHT);
      tab.set_block(bl);
     }
     break;
    }
    default:
     break;
   }
   table_lock.unlock();
   std::unique_lock<hierarchical_mutex> lock(mtx);
   if (flag == 2 || buf[0] == 113) {

    lock.unlock();

    tcsetattr(fd, TCSANOW, &saveterm);
    std::cout << "game over" << std::endl;
    exit(0);
   } else {
    lock.unlock();
   }
  }

  tcsetattr(0, TCSANOW, &saveterm);
 });
 thread printloop([&]() {
  while (1) {
   system("clear");
   std::unique_lock<hierarchical_mutex> table_lock(table_mtx);
   tab.paint();
   table_lock.unlock();
   this_thread::sleep_for(std::chrono::milliseconds(200 / tab.getLevel()));
   std::unique_lock<hierarchical_mutex> lock(mtx);

   if (flag == 2) {
    cout << "任意鍵退出" << endl;
    lock.unlock();
    break;
   } else
    lock.unlock();
  }
 });
 getkey.detach();
 printloop.detach();
 int dir, i, c;
 while (true) {
  //生成方塊
  std::unique_lock<hierarchical_mutex> table_lock(table_mtx);
//  std::unique_lock<std::mutex>table_lock(table_mtx);

  bl.create_block(tab.getWidth(), tab.getHeight());
  table_lock.unlock();
  //判斷游戲是否結束
  table_lock.lock();
  if (-1 == tab.set_block(bl)) {
   std::unique_lock<hierarchical_mutex> lock(mtx);
   flag = 2;
   lock.unlock();
   table_lock.unlock();
   while (1);
  } else
   table_lock.unlock();

  ///////////行動按鍵判定
  while (true) {
   this_thread::sleep_for(std::chrono::milliseconds(400 / tab.getLevel()));
   /////////////向下移動一格
   table_lock.lock();
   tab.clr_block(bl); //清空上一次方塊位置
   bl.move(Block::DOWN); //向下移動一步
   if (-1 == tab.set_block(bl)) { //是否觸底
    bl.move(Block::UP); //如果觸底,還原觸底前位置
    tab.set_block(bl);
    table_lock.unlock();
    break;
   }
   table_lock.unlock();
  }
  //如果滿行則消行
  table_lock.lock();
  for (i = 0; i < tab.getHeight(); i++) {
   if (tab.if_full(i)) { //是否滿行
    tab.clr_line(i); //如果是,消行
    tab.move_line(i); //將所消行的上面的棋盤信息下移
    i--;  //下移后,重新檢查這一行是否滿(可能出現幾行同時消去)
    tab.set_count(100); //記錄得分
   }
  }
  table_lock.unlock();
 }
 return 0;
}

grid.h

//
// Created by adl on 2020/7/17.
//

#ifndef UNTITLED_GRID_H
#define UNTITLED_GRID_H

struct grid {
 int x;
 int y;

 grid();
 grid(grid&&)noexcept ;
 grid(const grid&);
 grid(int x, int y);
 grid&operator=(const grid&);
 grid&operator=( grid&&);
 virtual ~grid();
}; //坐標



#endif //UNTITLED_GRID_H

grid.cpp

//
// Created by adl on 2020/7/17.
//

#include "grid.h"

grid::grid(int x, int y) : x(x), y(y) {}

grid::grid() : x(0), y(0) {}

grid::grid(grid &&rhs) noexcept: x(rhs.x), y(rhs.y) {

}

grid::~grid() {

}

grid::grid(const grid &rhs) : x(rhs.x), y(rhs.y) {
}

grid &grid::operator=(const grid &rhs) {
 if (this != &rhs) {
  x = rhs.x;
  y = rhs.y;
 }
 return *this;

}

grid &grid::operator=(grid &&rhs) {
 if (this != &rhs) {
  x = rhs.x;
  y = rhs.y;
 }
 return *this;
}

Block.h

//
// Created by adl on 2020/7/17.
//

#ifndef UNTITLED_BLOCK_H
#define UNTITLED_BLOCK_H

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <time.h>

#include<termios.h>
#include<fcntl.h>
#include <zconf.h>
#include "grid.h"

#define BLOCK_SIZE 4
#define SLEEP_TIME 500

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<memory>
#include <random>

class Block {
public:
 using Action =Block&(Block::*)();
 enum direct {
  UP, DOWN, LEFT, RIGHT
 };
 grid g[BLOCK_SIZE];

 Block() : center(0, 0), type(0) {}

 void def_block(grid g1, grid g2, grid g3, grid g4) {
  g[0] = g1;
  g[1] = g2;
  g[2] = g3;
  g[3] = g4;
 }

 void rotate() {
  //順時針旋
  int x, y;
  for (int i = 0; i < 4; i++) {
   x = g[i].x - center.x;
   y = g[i].y - center.y;
   g[i].x = center.x + y;
   g[i].y = center.y - x;

  }
 }

 Block &up() {
  for (int i = 0; i < 4; ++i) {
   g[i].y++;
  }
  center.y++;
  return *this;
 }

 Block &down() {
  for (int i = 0; i < 4; ++i) {
   g[i].y--;
  }
  center.y--;
  return *this;
 }

 Block &left() {
  for (int i = 0; i < 4; ++i) {
   g[i].x--;
  }
  center.x--;
  return *this;
 }

 Block &right() {
  for (int i = 0; i < 4; ++i) {
   g[i].x++;
  }
  center.x++;
  return *this;
 }

 void move(direct dir) {
  (this->*Menu[dir])();
 }


 void set_cen(grid g) {
  center = g;
 }

 grid get_cen() const {
  return center;
 }

 void set_type(int t) {
  type = t;
 }

 int get_type() const {
  return type;
 }

 void rotate_back() {
  //rotate的逆向
  int x, y;
  for (int i = 0; i < 4; i++) {
   x = g[i].x - center.x;
   y = g[i].y - center.y;
   g[i].x = center.x + y;
   g[i].y = center.y - x;

  }
 }

 void create_block(int x, int y) {
  unsigned int ran;
  grid g[BLOCK_SIZE];
  static std::uniform_int_distribution<unsigned> u(1, 7);
  static std::default_random_engine e(time(0));
  ran = u(e);
  switch (ran) {
   case 1: {
    g[0].x = x / 2;
    g[0].y = y - 3;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x;
    g[2].y = g[0].y + 2;
    g[3].x = g[0].x + 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(1);
    break;
   }
    //反L
   case 2: {
    g[0].x = x / 2;
    g[0].y = y - 3;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x;
    g[2].y = g[0].y + 2;
    g[3].x = g[0].x - 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(2);
    break;
   }
    //Z
   case 3: {
    g[0].x = x / 2;
    g[0].y = y - 2;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x + 1;
    g[2].y = g[0].y + 1;
    g[3].x = g[0].x - 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(3);
    break;
   }
    //反Z
   case 4: {
    g[0].x = x / 2;
    g[0].y = y - 2;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x + 1;
    g[2].y = g[0].y + 1;
    g[3].x = g[0].x - 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(4);
    break;
   }
    //田
   case 5: {
    g[0].x = x / 2;
    g[0].y = y - 2;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x + 1;
    g[2].y = g[0].y + 1;
    g[3].x = g[0].x + 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(5);
    break;
   }
    //1
   case 6: {
    g[0].x = x / 2;
    g[0].y = y - 3;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x;
    g[2].y = g[0].y + 2;
    g[3].x = g[0].x;
    g[3].y = g[0].y - 1;
    set_cen(g[0]);
    set_type(6);
    break;
   }
    //山
   case 7: {
    g[0].x = x / 2;
    g[0].y = y - 2;
    g[1].x = g[0].x;
    g[1].y = g[0].y + 1;
    g[2].x = g[0].x - 1;
    g[2].y = g[0].y;
    g[3].x = g[0].x + 1;
    g[3].y = g[0].y;
    set_cen(g[0]);
    set_type(7);
    break;
   }
   default:
    std::cerr << "someThing err!" << ran << std::endl;
  }
  def_block(g[0], g[1], g[2], g[3]);
 }

private:
 static Action Menu[];
 grid center;
 int type;
};

#endif //UNTITLED_BLOCK_H

Block.cpp

//
// Created by adl on 2020/7/17.
//

#include "Block.h"
Block::Action Block::Menu[]={
  &Block::up,
  &Block::down,
  &Block::left,
  &Block::right
};

Table.cpp

//
// Created by adl on 2020/7/17.
//

#include "Table.h"
#include "Block.h"

int Table::set_block(const Block &bl) {
 int x, y;
 for (int i = 0; i < 4; ++i) {
  x = bl.g[i].x;
  y = bl.g[i].y;
  //比如下降之后 table[x][y]上有方塊了
  if (table[x][y] != 0 || x >= width || x < 0 || y >= height || y < 0) {
   return -1;
  }
 }
 for (int i = 0; i < 4; ++i) {
  x = bl.g[i].x;
  y = bl.g[i].y;
  table[x][y] = 1;
 }
 return 0;
}

void Table::clr_block(const Block &bl) {
 int x, y;
 for (int i = 0; i < 4; ++i) {
  x = bl.g[i].x;
  y = bl.g[i].y;
  table[x][y] = 0;
 }
}

int Table::clr_line(int y) {
 if (y < 0 || y >= height) return -1;
 for (int i = 0; i < width; i++) {
  table[i][y] = 0;
 }
 return 0;
}

int Table::getHeight() const {
 return height;
}

int Table::getWidth() const {
 return width;
}

int Table::if_full(int y) {
 for (int i = 0; i < width; ++i) {
  if (table[i][y] == 0) return 0;
 }
 return 1;
}

int Table::get_table(int x, int y) {
 return table[x][y];
}

void Table::paint() {
 int i, j;
 system("clear");
 for (i = 0; i < width + 2; i++) std::cout << "-" << std::flush;
 std::cout << "\n" << std::flush;

 for (i = height - 1; i >= 0; i--) {
  std::cout << "|" << std::flush;
  for (j = 0; j < width; j++) {
   if (table[j][i] == 0) std::cout << " " << std::flush;
   else std::cout << "#" << std::flush;
   //&#9635;
  }
  if (i == 13)
   std::cout << "| 等級:" << getLevel() << std::endl;
  else if (i == 10)
   std::cout << "| 得分:" << get_count() << std::endl;
  else if (i == 7)
   std::cout << "| Press 'q' to quit!" << std::endl;
  else
   std::cout << "|" << std::endl;
 }
 for (i = 0; i < width + 2; i++) std::cout << "-" << std::flush;
 std::cout << "\n" << std::flush;
}

void Table::move_line(int y) {
 for (int i = y; i < height - 1; ++i) {
  for (int j = 0; j < width; ++j) {
   table[j][i] = table[j][i + 1];
  }
 }
}

void Table::set_count(int c) {
 count += c;
}

int Table::get_count() {
 return count;
}

int Table::getLevel() const {
 return level;
}

void Table::setLevel(int level) {
 Table::level = level;
}

Table.h

//
// Created by adl on 2020/7/17.
//

#ifndef UNTITLED_TABLE_H
#define UNTITLED_TABLE_H

#include <cstring>

#define TABLE_SIZE 20
class Block;
class Table {
public:

 Table():height(TABLE_SIZE),width(10),count(0),level(1){    //構造棋盤
  for (int i = 0; i < height; ++i) {
   for (int j = 0; j < width; ++j) {
    table[i][j]=0;
   }
  }
 }

 int getLevel() const;

 void setLevel(int level);

 Table(int x, int y,int level):height(y),width(x),count(0),level(level){
  for (int i = 0; i < height; ++i) {
   for (int j = 0; j < width; ++j) {
    table[i][j]=0;
   }
  }
 }
 int set_block(const Block &bl); //安設方塊
 void clr_block(const Block &bl);  //清除方塊
 int clr_line(int y);  //消行

 int getHeight() const;

 //獲取棋盤寬度
 int if_full(int y);  //判定是否滿行
 int get_table(int x, int y); //獲取棋盤上點信息
 void paint();   //繪制棋盤
 void move_line(int y);  //整行下移
 void set_count(int c);  //記錄得分
 int get_count();

 int getWidth() const;
 //獲取得分

private:
 int table[TABLE_SIZE][TABLE_SIZE];//棋盤
 int height, width;  //棋盤的高和寬
 int count;   //得分
 int level;

};

#endif //UNTITLED_TABLE_H

hierarchical_mutex.h

//
// Created by adl on 2020/7/18.
//

#ifndef UNTITLED_HIERARCHICAL_MUTEX_H
#define UNTITLED_HIERARCHICAL_MUTEX_H
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<memory>
#include <exception>
#include <mutex>
#include <thread>
#include <climits>

class hierarchical_mutex{
private:
 std::mutex internal_mutex;
 uint64_t const hierarchical_value;
 uint64_t previous_value;
 static thread_local uint64_t this_thread_hierarchical_value;

 void check_for_hierarchy() noexcept(false) {
  if(this_thread_hierarchical_value <= hierarchical_value){
   throw std::logic_error("mutex hierarchical violated.");
  }
 }

 void update_hierarchy_value(){
  previous_value = this_thread_hierarchical_value;
  this_thread_hierarchical_value = hierarchical_value;
 }

public:
 constexpr explicit hierarchical_mutex(uint64_t value) :
   hierarchical_value(value), previous_value(0) {}

 void lock() noexcept(false) {
  check_for_hierarchy();
  internal_mutex.lock();
  update_hierarchy_value();
 }

 void unlock(){
  this_thread_hierarchical_value = previous_value;
  internal_mutex.unlock();
 }

 bool try_lock() noexcept(false) {
  check_for_hierarchy();
  if(!internal_mutex.try_lock()) return false;
  update_hierarchy_value();
  return true;
 }
};


#endif //UNTITLED_HIERARCHICAL_MUTEX_H

積累的經驗:

1.生成隨機數的uniform_int_distribution,defualt_random_engine(time(0))使用時必須用static,缺點是多次執行程序的第一次生成的數字是一樣的

2.與c++primer p743類似,使用成員指針函數表可以使用戶調用的函數更加明了。

3.給互斥鎖加權值,并以權值大小順序加鎖,可以保證線程加鎖順序一致,避免死鎖(出現則拋出異常)(這個純粹活學活用,因為c++鎖和線程接觸不多)

4.thread xxx([&](){})是可以放在函數內部的線程

5.利用select監控標準輸入

6.利用tcgetattr,tcsetaddr,termiosi結構體
nt.c_lflag &= ~ECHO; nt.c_lflag &= ~ISIG; nt.c_lflag &= ~ICANON;
可以在linux關閉回顯,實現getch

7.this_thread::sleep_for(std::chrono::milliseconds(400 / tab.getLevel()));可以咋線程中實現毫秒級別睡眠

8.類中靜態對象初始化可以寫在其對應.cpp文件中

反思:

未使用類的繼承,各種方塊理論可以寫成子類,因為主線程一開始直接使用了Block對象,后期不容易修改.

看完上述內容,是不是對C++如何實現俄羅斯方塊有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

娄烦县| 左权县| 长白| 稷山县| 韶山市| 兰坪| 文水县| 绥棱县| 从江县| 奇台县| 玛纳斯县| 抚宁县| 和田县| 工布江达县| 清涧县| 宁陕县| 双柏县| 平远县| 英德市| 新源县| 惠来县| 定州市| 宣威市| 黑河市| 阿坝| 安阳县| 伊吾县| 安溪县| 小金县| 固阳县| 霍州市| 武汉市| 合川市| 黄大仙区| 呼伦贝尔市| 泸定县| 大邑县| 安岳县| 江津市| 镇平县| 莆田市|