fork download
  1. #pragma warning(disable:4710)
  2. #pragma warning(disable:4711)
  3. #pragma warning(disable:4820)
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <ctime>
  7. #include <cstdlib>
  8. #include <climits>
  9. using namespace std;
  10. #define ROW 5//縦
  11. #define COL 6//横
  12. typedef char F_T;//盤面型
  13. typedef char T_T;//手数型
  14. enum { EVAL_NONE = 0, EVAL_FALL, EVAL_SET, EVAL_FS, EVAL_COMBO };
  15.  
  16. //初期配置生成関数
  17. void init(F_T field[ROW][COL]);
  18.  
  19. //ドロップの落下処理関数
  20. void fall(F_T field[ROW][COL]);
  21.  
  22. //空マスを埋める関数
  23. void set(F_T field[ROW][COL], int force);
  24.  
  25. //盤面表示関数
  26. void show_field(F_T field[ROW][COL]);
  27.  
  28. //整数乱数
  29. unsigned int rnd(int mini, int maxi);
  30.  
  31. //上下左右に連結しているドロップを再帰的に探索していく関数
  32. int chain(int nrw, int ncl, int d, F_T field[ROW][COL],F_T chkflag[ROW][COL], F_T delflag[ROW][COL]);
  33.  
  34. //最終的にコンボが発生したか、さらにどのドロップが消えるのか判定する関数
  35. int check(F_T field[ROW][COL], F_T delflag[ROW][COL], F_T t_erase[ROW][COL]);
  36.  
  37. //コンボ数判定関数
  38. int evaluate(F_T field[ROW][COL], int flag);
  39.  
  40. //落とし有り、落ちコン無しコンボ数判定関数
  41. int sum_e(F_T field[ROW][COL]);
  42.  
  43. //落としも落ちコンも有りコンボ数判定関数
  44. int sum_evaluate(F_T field[ROW][COL]);
  45.  
  46. void show_field(F_T field[ROW][COL]) {
  47. for (int i = 0; i < ROW; i++) {
  48. for (int j = 0; j < COL; j++) {
  49. printf("%d", field[i][j]);
  50. }
  51. printf("\n");
  52. }
  53. }
  54. void fall(F_T field[ROW][COL]) {
  55. for (int j = 0; j < COL; j++) {
  56. int tgt;
  57. for (tgt = ROW - 1; tgt >= 0 && field[tgt][j] != 0; tgt--);
  58. for (int i = tgt - 1; i >= 0; i--) {
  59. if (field[i][j] != 0) {
  60. F_T c = field[i][j];
  61. field[i][j] = 0;
  62. field[tgt][j] = c;
  63. tgt--;
  64. }
  65. }
  66. }
  67. }
  68. void init(F_T field[ROW][COL]) { set(field, !0); }
  69. void set(F_T field[ROW][COL], int force) {
  70. for (int i = 0; i < ROW; i++) {
  71. for (int j = 0; j < COL; j++) {
  72. if (field[i][j] == 0 || force) {//空マスだったらうめる
  73. field[i][j] = (F_T)rnd(force ? 0 : 1, 6);//1-6の整数乱数
  74. }
  75. }
  76. }
  77. }
  78. int chain(int nrw, int ncl, int d, F_T field[ROW][COL],
  79. F_T chkflag[ROW][COL], F_T delflag[ROW][COL]) {
  80. int count = 0;
  81. #define CHK_CF(Y,X) (field[Y][X] == d && chkflag[Y][X] == 0)
  82. //連結している同じ色のドロップが未探索だったら
  83. if (CHK_CF(nrw, ncl)) {
  84. ++count; //連結ドロップ数の更新
  85. chkflag[nrw][ncl] = //探索済みにする
  86. delflag[nrw][ncl] = 1;//コンボがつながる可能性があるので、1に設定
  87. //以下上下左右に連結しているドロップを再帰的に探索していく
  88. if (0 < nrw && CHK_CF(nrw - 1, ncl)) {
  89. count += chain(nrw - 1, ncl, d, field, chkflag, delflag);
  90. }
  91. if (nrw < ROW - 1 && CHK_CF(nrw + 1, ncl)) {
  92. count += chain(nrw + 1, ncl, d, field, chkflag, delflag);
  93. }
  94. if (0 < ncl && CHK_CF(nrw, ncl - 1)) {
  95. count += chain(nrw, ncl - 1, d, field, chkflag, delflag);
  96. }
  97. if (ncl < COL - 1 && CHK_CF(nrw, ncl + 1)) {
  98. count += chain(nrw, ncl + 1, d, field, chkflag, delflag);
  99. }
  100. }
  101. return count;
  102. }
  103. int evaluate(F_T field[ROW][COL], int flag) {//コンボ数判定関数
  104. int combo = 0;
  105. while (1) {
  106. int cmb = 0;
  107. F_T chkflag[ROW][COL] = { 0 }; //未探索ドロップか否か格納する配列
  108. F_T t_erase[ROW][COL] = { 0 }; //消去ドロップか否か格納する配列
  109. for (int row = 0; row < ROW; row++) {
  110. for (int col = 0; col < COL; col++) {
  111. if (chkflag[row][col] == 0 && field[row][col] != 0) {
  112. //未探索ドロップで、空マスじゃない場合
  113. F_T delflag[ROW][COL] = { 0 }; //消去ドロップがありうるか格納する配列
  114. int max_count = chain(row, col, field[row][col],
  115. field, chkflag, delflag); //連結ドロップを探索する
  116. if (max_count >= 3) {//3つ以上連結している場合、コンボが発生しうる
  117. if (check(field, delflag, t_erase) == 1) { cmb++; }//コンボ発生
  118. }
  119. }
  120. }
  121. }
  122. combo += cmb;
  123. //コンボが発生しなかったら終了
  124. if (cmb == 0 || 0 == (flag&EVAL_COMBO)) { break; }
  125. for (int row = 0; row < ROW; row++) {
  126. for (int col = 0; col < COL; col++) {
  127. //コンボになったドロップは空になる。
  128. if (t_erase[row][col] != 0) { field[row][col] = 0; }
  129. }
  130. }
  131. if (flag&EVAL_FALL)fall(field);//落下処理発生
  132. if (flag&EVAL_SET)set(field, 0);//落ちコン発生
  133. }
  134. return combo;
  135. }
  136. int sum_e(F_T field[ROW][COL]) {//落とし有り、落ちコン無しコンボ数判定関数
  137. return evaluate(field, EVAL_FALL | EVAL_COMBO);
  138. }
  139. int sum_evaluate(F_T field[ROW][COL]) {//落としも落ちコンも有りコンボ数判定関数
  140. return evaluate(field, EVAL_FS | EVAL_COMBO);
  141. }
  142. //最終的にコンボが発生したか、さらにどのドロップが消えるのか判定する関数
  143. int check(F_T field[ROW][COL], F_T delflag[ROW][COL], F_T t_erase[ROW][COL]) {
  144. int cmb = 0;
  145. for (int row = 0; row < ROW; row++) {
  146. for (int col = 0; col < COL - 2; col++) {
  147. if (delflag[row][col] != 0 &&
  148. delflag[row][col + 1] != 0 &&
  149. delflag[row][col + 2] != 0 &&
  150. field[row][col] == field[row][col + 1] &&
  151. field[row][col] == field[row][col + 2]) {
  152. //コンボが発生しうるドロップでなおかつ、横に3つつながってたら、
  153. //その3つのドロップはコンボになるので消える。
  154. t_erase[row][col] =
  155. t_erase[row][col + 1] =
  156. t_erase[row][col + 2] = 1;
  157. cmb = 1;
  158. //for (col += 3; col < COL; col++) {
  159. // if(delflag[row][col] != 0 &&
  160. // field[row][col] == field[row][col - 1]) {
  161. // t_erase[row][col] = 1;
  162. //} }
  163. }
  164. }
  165. }
  166. for (int col = 0; col < COL; col++) {
  167. for (int row = 0; row < ROW - 2; row++) {
  168. if (delflag[row][col] != 0 &&
  169. delflag[row + 1][col] != 0 &&
  170. delflag[row + 2][col] != 0 &&
  171. field[row][col] == field[row + 1][col] &&
  172. field[row][col] == field[row + 2][col]) {
  173. //コンボが発生しうるドロップでなおかつ、縦に3つつながってたら、
  174. //その3つのドロップはコンボになるので消える。
  175. t_erase[row][col] =
  176. t_erase[row + 1][col] =
  177. t_erase[row + 2][col] = 1;
  178. cmb = 1;
  179. //for (row += 3; row < ROW; row++) {
  180. // if(delflag[row][col] != 0 &&
  181. // field[row][col] == field[row - 1][col]) {
  182. // t_erase[row][col] = 1;
  183. //} }
  184. }
  185. }
  186. }
  187. //cmb=0ならコンボは発生しなかった。1ならコンボが発生した
  188. return cmb;
  189. }
  190. unsigned int rnd(int mini, int maxi) {//xorshift整数乱数
  191. static unsigned int x = 123456789;
  192. static unsigned int y = 362436069;
  193. static unsigned int z = 521288629;
  194. static unsigned int w = 0U;
  195. if (w == 0U) { w = time(NULL) % INT_MAX; }
  196. unsigned int t;
  197. t = x ^ (x << 11);
  198. x = y; y = z; z = w;
  199. w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  200. return mini + (w % (maxi - mini + 1));
  201. }
  202. int main() {
  203. int i;
  204. for (i = 0; i < 1; i++) {//1問解く
  205. F_T f_field[ROW][COL]; //盤面
  206. printf("problem:%d\n", i + 1);
  207. init(f_field); set(f_field, 0);//初期盤面生成
  208. show_field(f_field);//盤面表示
  209. printf("%dCombo\n", sum_e(f_field));//コンボ数表示
  210. }
  211.  
  212.  
  213. return 0;
  214. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
problem:1
224143
541634
622355
564642
111556
1Combo