吹水:
今日得闲没野做,就捻着搵点野料下。
我玩过2048,觉得规则挺简单的,应该挺好入手的。
毕竟,也是开源的。网上也存在很多教材或自定义,神马的。
于是,我本着尝试的态度,不看教程,能否山寨一个出来。
分析:去官网http://gabrielecirulli.github.io/2048/玩上几盘,一步一步地摸索其规则。
最后,经过一个下午和傍晚的时间,我实现了大致的功能,也不清楚是否和原版100%相同。
而且程序效率也不高,在此就不详解我自己的做法了。有兴趣的人,可自行参照网上的教程。
此帖,自娱自乐,目的只有一个:锻炼自己的编码能力和分析步骤。
备注:控制台版,使用C++语言
Grid.h
/***************************************************************
*程序名称:2048
*内容摘要:练习
*其它说明:无
*当前版本:V1.0
*作 者:tbz
*完成日期:2014年5月8日
***************************************************************/
#ifndef _GIRD_H_
#define _GIRD_H_
//实现4X4的方格,并提供移动、检测输赢等操作
class Grid
{
public:
explicit Grid();
void print();
void move(char action);
bool isWon();
bool isLost();
private:
int position[4][4];
//这四个函数原理一致
bool moveLeft();
bool moveRight();
bool moveUp();
bool moveDown();
//辅助函数
bool isExistEqual(int row, int column);
void generateEntry(int count);
int& at(int row, int column);
int random(int min, int max);
};
#endif/***************************************************************
*程序名称:2048
*内容摘要:练习
*其它说明:无
*当前版本:V1.0
*作 者:tbz
*完成日期:2014年5月8日
***************************************************************/
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include "Grid.h"
using namespace std;
//从1开始计数
int& Grid::at(int row, int column)
{
return position[row-1][column-1];
}
//生成某范围的随机数
int Grid::random(int min, int max)
{
return ((rand() % (max-min+1)) + min);
}
//建立4X4表格,并初始化
Grid::Grid()
{
srand(time(0));
for (int row = 1; row <= 4; ++row)
for (int column = 1; column <= 4; ++column)
{
at(row, column) = 0;
}
//放置2个数
generateEntry(2);
}
//生成几个数,不重复
void Grid::generateEntry(int count)
{
int x = 0, y = 0, value = 0;
for (int i = 0; i < count; ++i)
{
bool valid = false;
while(!valid)
{
x = random(1, 4);
y = random(1, 4);
value = random(1, 2) * 2;
if (!at(x, y))
{
valid = true;
at(x, y) = value;
}
}
}
}
//视图绘制
void Grid::print()
{
cout << " ------------2048------------" << endl;
cout << " ____________________________" << endl;
for (int i = 1; i <= 4; ++i)
{
cout << "|";
for (int j = 1; j <= 4; ++j)
{
int temp = at(i, j);
if (temp)
cout << " " << setw(4) << temp << ". ";
else
cout << " " << setw(4) << ‘ ‘ << ". ";
}
cout << "|" << endl;
}
cout << " ----------------------------" << endl;
}
void Grid::move(char action)
{
bool moved = false;
switch(action)
{
case ‘a‘:
case ‘A‘:
moved = moveLeft();
break;
case ‘d‘:
case ‘D‘:
moved = moveRight();
break;
case ‘w‘:
case ‘W‘:
moved = moveUp();
break;
case ‘s‘:
case ‘S‘:
moved = moveDown();
break;
}
if (moved)
generateEntry(1);
}
//检测
bool Grid::isWon()
{
for (int i = 1; i <= 4; ++i)
{
for (int j = 1; j <= 4; ++j)
{
if (at(i, j) == 2048)
return true;
}
}
return false;
}
bool Grid::isExistEqual(int row, int column)
{
bool ret = false;
//行检测
if (row == 1)
{
ret = (at(row, column) == at(row+1, column));
}
else if (row == 4)
{
ret = (at(row, column) == at(row-1, column));
}
else
{
ret = (at(row, column) == at(row-1, column)) && (at(row, column) == at(row+1, column));
}
//列检测
if (column == 1)
{
ret = (at(row, column) == at(row, column+1));
}
else if (column == 4)
{
ret = (at(row, column) == at(row, column-1));
}
else
{
ret = (at(row, column) == at(row, column-1)) && (at(row, column) == at(row, column+1));
}
return ret;
}
bool Grid::isLost()
{
for (int i = 1; i <= 4; ++i)
{
for (int j = 1; j <= 4; ++j)
{
if (!at(i, j))
return false;
else
{
if (isExistEqual(i, j))
return false;
}
}
}
return true;
}
//下
bool Grid::moveDown()
{
int top = 1, bottom = 4;
bool moved = false;
for (int column = 1; column <= 4; ++column)
{
//相同的数字合并
int last = 0, pos = 0;
for (int work = bottom; work >= top; --work)
{
if (at(work, column))
{
if (last)
if (at(work, column) == last)
{
at(work, column) = 0;
at(pos, column) *= 2;
moved = true;
last = 0;
pos = 0;
}
else
{
last = at(work, column);
pos = work;
}
else if (!last)
{
last = at(work, column);
pos = work;
}
}
}
//将数字往栈底挤
for (int work = bottom; work >= top; --work)
{
if (at(work, column))
{
for (int i = work; i <= bottom-1; ++i)
{
if (!at(i+1, column))
{
swap(at(i, column), at(i+1, column));
moved = true;
}
else break;
}
}
}
}
return moved;
}
//上
bool Grid::moveUp()
{
int top = 4, bottom = 1;
bool moved = false;
for (int column = 1; column <= 4; ++column)
{
//相同的数字合并
int last = 0, pos = 0;
for (int work = bottom; work <= top; ++work)
{
if (at(work, column))
{
if (last)
if (at(work, column) == last)
{
at(work, column) = 0;
at(pos, column) *= 2;
moved = true;
last = 0;
pos = 0;
}
else
{
last = at(work, column);
pos = work;
}
else if (!last)
{
last = at(work, column);
pos = work;
}
}
}
//将数字往底挤
for (int work = bottom; work <= top; ++work)
{
if (at(work, column))
{
for (int i = work; i >= bottom+1; --i)
{
if (!at(i-1, column))
{
swap(at(i, column), at(i-1, column));
moved = true;
}
else break;
}
}
}
}
return moved;
}
//左
bool Grid::moveLeft()
{
int top = 4, bottom = 1;
bool moved = false;
for (int row = 1; row <= 4; ++row)
{
//相同的数字合并
int last = 0, pos = 0;
for (int work = bottom; work <= top; ++work)
{
if (at(row, work))
{
if (last)
if (at(row, work) == last)
{
at(row, work) = 0;
at(row,pos) *= 2;
moved = true;
last = 0;
pos = 0;
}
else
{
last = at(row, work);
pos = work;
}
else if (!last)
{
last = at(row, work);
pos = work;
}
}
}
//将数字往底挤
for (int work = bottom; work <= top; ++work)
{
if (at(row, work))
{
for (int i = work; i >= bottom+1; --i)
{
if (!at(row, i-1))
{
swap(at(row, i), at(row, i-1));
moved = true;
}
else break;
}
}
}
}
return moved;
}
//右
bool Grid::moveRight()
{
int top = 1, bottom = 4;
bool moved = false;
for (int row = 1; row <= 4; ++row)
{
//相同的数字合并
int last = 0, pos = 0;
for (int work = bottom; work >= top; --work)
{
if (at(row, work))
{
if (last)
if (at(row, work) == last)
{
at(row, work) = 0;
at(row,pos) *= 2;
moved = true;
last = 0;
pos = 0;
}
else
{
last = at(row, work);
pos = work;
}
else if (!last)
{
last = at(row, work);
pos = work;
}
}
}
//将数字往底挤
for (int work = bottom; work >= top; --work)
{
if (at(row, work))
{
for (int i = work; i <= bottom-1; ++i)
{
if (!at(row, i+1))
{
swap(at(row, i), at(row, i+1));
moved = true;
}
else break;
}
}
}
}
return moved;
}
/***************************************************************
*程序名称:2048
*内容摘要:练习
*其它说明:无
*当前版本:V1.0
*作 者:tbz
*完成日期:2014年5月8日
***************************************************************/
#include <cstdlib>
#include <conio.h>
#include "Grid.h"
#include <iostream>
using namespace std;
bool isNeed(char c)
{
switch (c)
{
case ‘a‘:case ‘s‘:case ‘d‘:case ‘w‘:
case ‘A‘:case ‘S‘:case ‘D‘:case ‘W‘:
return true;
}
return false;
}
int main(int argc, char const *argv[])
{
Grid game;
//game flow control
while (true)
{
system("cls");
game.print();
if (game.isWon())
{
cout << endl << "Congratulation! You won!" << endl;
cout << "Press any key to exit." << endl;
getch();
return 0;
}
if (game.isLost())
break;
//Promt
cout << endl;
cout << "A -> Left, D -> Right, W -> Up, S -> Down. (K -> Exit)" << endl;
char input = getch();
if (input == ‘k‘)
return 0;
if (!isNeed(input)) continue;
game.move(input);
}
cout << "Sorry! You lose." << endl;
getch();
return 0;
}总结:
分析很重要。
每开发一个独立功能,就测试一下,可减少后期调试的痛苦。
[Practice]山寨2048之Terminal版,布布扣,bubuko.com
原文地址:http://blog.csdn.net/tbz888/article/details/25335555