游戏展示
文章目录
界面展示
游戏中过程解析
-
游戏每秒进行的操作
- 队头元素入队尾
- 队头出队
- 从右上角开始顺时针展示队列 元素较少时会居中展示
- 清除屏幕 显示下一帧
- 获取键盘数据
-
按下s / S
- 子弹入栈
- 判断是否有三个重复元素 是 删除
-
按下w / W
- 子弹出栈
- 队列中目标位置插入数据
- 判断是否有三个重复元素 是 删除
-
队列元素小于等于三
- 胜利游戏 游戏结束
-
队列元素大于等于一圈的元素数量
- 游戏失败 游戏结束
数据结构
- -(为游戏服务有些地方未通用化)
-
栈
//构造栈 typedef struct stack { char st[maxn]; int len = 0; void push(char q) { if (len >= maxn) { printf("子弹装满了哦!!!"); exit(1); } else { st[++len] = q; } } void pop() { if (len == 0) { printf("没有子弹哦!!!"); exit(1); } else { len--; } } char top() { if (len == 0) { printf("没有子弹哦!!!"); return NULL; } else { return st[len]; } } bool empty() { if (len == 0) return true; else { return false; } } };
-
链表
//节点 typedef struct node { char date; node* next; }node; //构造链表 typedef struct list { int size; node* elem; void initlist() { list* p = (list*)malloc(sizeof(list)); node* q = (node*)malloc(sizeof(node)); q->next = NULL; p->elem = q; p->size = 0; *this = *p; } node* creatlist(int n, int alrank) { node* t = elem; size = n; srand(time(NULL)); for (int i = 1; i <= n; i++) { node* q = (node*)malloc(sizeof(node)); q->next = NULL; q->date = (rand() % alrank) + 'A'; t->next = q; t = q; } return t; } //直接插入无需循环 bool insertlist(node* p, char date) { if(p== (node*)0xCCCCCCCC) return false; size++; node* q = (node*)malloc(sizeof(node)); q->date = date; q->next = p->next; // p->next = q; return true; } bool deletlist(node* p) { size--; node* q = p->next; if (p->next != (node*)0xDDDDDDDD) { p->next = q->next; free(q); return true; } return false; } //仅测试时使用 bool showlist() { node* p = elem->next; printf("长为%d的表为:\n", size); while (p) { printf("%c ", p->date); p = p->next; } putchar('\n'); return true; } }list;
-
队列
//游戏用到大量的插入删除故使用链表队列 typedef struct queue { list k; int len = 0; //front 指向头结点 node* front, * rear; void innit(int n, int alrank) { k.initlist(); rear = k.creatlist(n, alrank); // rear = prerear->next; len = k.size; front = k.elem; } char gethead() { return front->next->date; } char getrear() { return rear->date; } void in() { if (len) { k.insertlist(rear, gethead()); rear = rear->next; len = k.size; } else { printf("队列空"); } } void out() { k.deletlist(front); len = k.size; } void show() { k.showlist(); } void insert(node* p, char a) { k.insertlist(p, a); } bool empty() { if (len == 0) return true; else { return false; } } }queue;
-
游戏对象
typedef struct game { //标记游戏结束 int flag = 0; //当前点击 char click = ' '; //等级规则 用于计算字母个数 int rule = 7; //存放目标 queue k; //存放子弹 stack bullets; //字母种类难度等级 int alrank = 5; //字母数量难度等级 int rank; //速度难度等级 int speedrk; //子弹打入位置--插入位置的前一位置 node* insertposition; //游戏界面 char gra[200][200] = {}; //界面与左边框距离 dx 个空格 上边距 dy 个空格 int dx = 10, dy = 8; //炮台 char pt[7][13] = { " | | ", " | | ", " | | ", " #| |# ", " ##| |## ", " ###| |### ", "<<<<< >>>>>", }; //将难度等级转化为字母个数 int getcnt() { return 3 * rank * rule - 2; } void innit(int n) { srand(time(NULL)); rank = n; k.innit(getcnt(), alrank); //创建线程 pthread_t as; pthread_create(&as, NULL, getMsg, this); } //bullet : 子弹 void getbullet() { bullets.push(rand() % alrank + 'A'); } //消除三个相同的 void ck() { node* o = k.front; while (k.len>=3&&o->next) { if (!o->next->next) break; if (!o->next->next->next) break; if (o->next->date == o->next->next->date && o->next->date == o->next->next->next->date) { node* a = o, * b = o->next, * c = o->next->next; k.k.deletlist(c); k.k.deletlist(b); k.k.deletlist(a); k.len = k.k.size; } o = o->next; } } //开火 void fire() { char b; if (!bullets.empty()) { b = bullets.top(); bullets.pop(); k.insert(insertposition, b); } else { printf("请先装填子弹哦!!!"); } ck(); } bool win() { if (k.len <= 3) return true; else { return false; } } bool lost() { if (k.len >= getcnt() + 2 * rule && !win()) { return true; } else { return false; } } //测试 void delt() { node* o = k.front; node* a = o; k.k.deletlist(a); k.len = k.k.size; } //显示界面 void next() { k.in(); k.out(); } void show() { printf("游戏规则:\n 1 w发射 s压弹\n 2 当字母数量小于等于3时获胜\n 3 当个数占满一圈时失败\n 4 当且仅当有三个连续字母相同时会消去\n"); for (int i = 0; i < 200; i++) { for (int j = 0; j < 200; j++) { if (j == dx + 2 * (rule - 1) + 4 * (rule - rule / 2) + 2) { gra[i][j] = '\0'; break; } else { gra[i][j] = ' '; } } } node* p = k.front->next; //居中 int dp = (getcnt() - k.len) / 2 ; dp = (getcnt() - k.len) / 2; //射击位置 int mid = dx + 1 + rule - 1 + 2 * (rule - rule / 2); { //绘制右边框 for (int i = dy; p && i <= rule / 2 + dy - 1; i++) { if (dp-- > 0) { continue; } gra[i][dx + 2 * (rule - 1) + 4 * (rule - rule / 2) + 1] = p->date; p = p->next; } //绘制下边框 for (int i = dx + 2 * (rule - 1) + 4 * (rule - rule / 2); p && i >= dx + 3; i -= 2) { if (dp-- > 0) { continue; } if (i - 1 == mid) { insertposition = p; } gra[rule / 2 + dy - 1][i - 1] = p->date; p = p->next; } //绘制左边框 for (int i = rule / 2 + dy - 1; p && i >= dy; i--) { gra[i][dx + 1] = p->date; p = p->next; } //绘制上边框 for (int i = dx + 3; p && i <= dx + 2 * (rule - 1) + 4 * (rule - rule / 2); i += 2) { gra[dy][i] = p->date; p = p->next; } } //绘制炮台 { gra[rule / 2 + dy][mid - 1] = '|'; gra[rule / 2 + dy][mid + 1] = '|'; int dypt = 5; //显示炮弹位次 int ct = bullets.len; for (int i = rule / 2 + dy + dypt; i < rule / 2 + dy + dypt + 7; i++) { for (int j = mid - 5; j <= mid + 6; j++) { if (j == mid && ct > 0) { gra[i][j] = bullets.st[ct--]; } else { gra[i][j] = pt[i - rule / 2 - dy - dypt][j - mid + 5]; } } } } for (int i = 0; i < dy + rule + 7; i++) { puts(gra[i]); } } }game;
特色
原代码
/*
Name: 消消乐小游戏
Copyright: 1913041130
Author: 张文涛
Date: 13/04/21 11:59
Description:
*/
#pragma warning( disable:4996)
#include"stdio.h"
#include"malloc.h"
#include"stdlib.h"
#include "time.h"
#include "string.h"
#include "windows.h"
#include "conio.h"
#include "iostream"
#include "pthread.h"
#include"unistd.h"
const int maxn = 1e3;
//获取当前点击
void* getMsg(void* f);
//构造栈
typedef struct stack {
char st[maxn];
int len = 0;
void push(char q) {
if (len >= maxn) {
printf("子弹装满了哦!!!");
exit(1);
}
else {
st[++len] = q;
}
}
void pop() {
if (len == 0) {
printf("没有子弹哦!!!");
exit(1);
}
else {
len--;
}
}
char top() {
if (len == 0) {
printf("没有子弹哦!!!");
return NULL;
}
else {
return st[len];
}
}
bool empty() {
if (len == 0) return true;
else {
return false;
}
}
};
//节点
typedef struct node {
char date;
node* next;
}node;
//构造链表
typedef struct list {
int size;
node* elem;
void initlist() {
list* p = (list*)malloc(sizeof(list));
node* q = (node*)malloc(sizeof(node));
q->next = NULL;
p->elem = q;
p->size = 0;
*this = *p;
}
node* creatlist(int n, int alrank) {
node* t = elem;
size = n;
srand(time(NULL));
for (int i = 1; i <= n; i++) {
node* q = (node*)malloc(sizeof(node));
q->next = NULL;
q->date = (rand() % alrank) + 'A';
t->next = q;
t = q;
}
return t;
}
//直接插入无需循环
bool insertlist(node* p, char date) {
if(p== (node*)0xCCCCCCCC) return false;
size++;
node* q = (node*)malloc(sizeof(node));
q->date = date;
q->next = p->next;
//
p->next = q;
return true;
}
bool deletlist(node* p) {
size--;
node* q = p->next;
if (p->next != (node*)0xDDDDDDDD) {
p->next = q->next;
free(q);
return true;
}
}
//仅测试时使用
bool showlist() {
node* p = elem->next;
printf("长为%d的表为:\n", size);
while (p) {
printf("%c ", p->date);
p = p->next;
}
putchar('\n');
return true;
}
}list;
//游戏用到大量的插入删除故使用链表队列
typedef struct queue {
list k;
int len = 0;
//front 指向头结点
node* front, * rear;
void innit(int n, int alrank) {
k.initlist();
rear = k.creatlist(n, alrank);
// rear = prerear->next;
len = k.size;
front = k.elem;
}
char gethead() {
return front->next->date;
}
char getrear() {
return rear->date;
}
void in() {
if (len) {
k.insertlist(rear, gethead());
rear = rear->next;
len = k.size;
}
else {
printf("队列空");
}
}
void out() {
k.deletlist(front);
len = k.size;
}
void show() {
k.showlist();
}
void insert(node* p, char a) {
k.insertlist(p, a);
}
bool empty() {
if (len == 0) return true;
else {
return false;
}
}
}queue;
typedef struct game {
//标记游戏结束
int flag = 0;
//当前点击
char click = ' ';
//等级规则 用于计算字母个数
int rule = 7;
//存放目标
queue k;
//存放子弹
stack bullets;
//字母种类难度等级
int alrank = 5;
//字母数量难度等级
int rank;
//速度难度等级
int speedrk;
//子弹打入位置--插入位置的前一位置
node* insertposition;
//游戏界面
char gra[200][200] = {};
//界面与左边框距离 dx 个空格 上边距 dy 个空格
int dx = 10, dy = 8;
//炮台
char pt[7][13] = {
" | | ",
" | | ",
" | | ",
" #| |# ",
" ##| |## ",
" ###| |### ",
"<<<<< >>>>>",
};
//将难度等级转化为字母个数
int getcnt() {
return 3 * rank * rule - 2;
}
void innit(int n) {
srand(time(NULL));
rank = n;
k.innit(getcnt(), alrank);
//创建线程
pthread_t as;
pthread_create(&as, NULL, getMsg, this);
}
//bullet : 子弹
void getbullet() {
bullets.push(rand() % alrank + 'A');
}
//消除三个相同的
void ck() {
node* o = k.front;
while (k.len>=3&&o->next) {
if (!o->next->next) break;
if (!o->next->next->next) break;
if (o->next->date == o->next->next->date && o->next->date == o->next->next->next->date) {
node* a = o, * b = o->next, * c = o->next->next;
k.k.deletlist(c);
k.k.deletlist(b);
k.k.deletlist(a);
k.len = k.k.size;
}
o = o->next;
}
}
//开火
void fire() {
char b;
if (!bullets.empty()) {
b = bullets.top();
bullets.pop();
k.insert(insertposition, b);
}
else {
printf("请先装填子弹哦!!!");
}
ck();
}
bool win() {
if (k.len <= 3) return true;
else {
return false;
}
}
bool lost() {
if (k.len >= getcnt() + 2 * rule && !win())
{
return true;
}
else {
return false;
}
}
//测试
void delt() {
node* o = k.front;
node* a = o;
k.k.deletlist(a);
k.len = k.k.size;
}
//显示界面
void next() {
k.in();
k.out();
}
void show() {
printf("游戏规则:\n 1 w发射 s压弹\n 2 当字母数量小于等于3时获胜\n 3 当个数占满一圈时失败\n 4 当且仅当有三个连续字母相同时会消去\n");
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 200; j++) {
if (j == dx + 2 * (rule - 1) + 4 * (rule - rule / 2) + 2) {
gra[i][j] = '\0';
break;
}
else {
gra[i][j] = ' ';
}
}
}
node* p = k.front->next;
//居中
int dp = (getcnt() - k.len) / 2 ;
dp = (getcnt() - k.len) / 2;
//射击位置
int mid = dx + 1 + rule - 1 + 2 * (rule - rule / 2);
{
//绘制右边框
for (int i = dy; p && i <= rule / 2 + dy - 1; i++) {
if (dp-- > 0) {
continue;
}
gra[i][dx + 2 * (rule - 1) + 4 * (rule - rule / 2) + 1] = p->date;
p = p->next;
}
//绘制下边框
for (int i = dx + 2 * (rule - 1) + 4 * (rule - rule / 2); p && i >= dx + 3; i -= 2) {
if (dp-- > 0) {
continue;
}
if (i - 1 == mid) {
insertposition = p;
}
gra[rule / 2 + dy - 1][i - 1] = p->date;
p = p->next;
}
//绘制左边框
for (int i = rule / 2 + dy - 1; p && i >= dy; i--) {
gra[i][dx + 1] = p->date;
p = p->next;
}
//绘制上边框
for (int i = dx + 3; p && i <= dx + 2 * (rule - 1) + 4 * (rule - rule / 2); i += 2) {
gra[dy][i] = p->date;
p = p->next;
}
}
//绘制炮台
{
gra[rule / 2 + dy][mid - 1] = '|';
gra[rule / 2 + dy][mid + 1] = '|';
int dypt = 5;
//显示炮弹位次
int ct = bullets.len;
for (int i = rule / 2 + dy + dypt; i < rule / 2 + dy + dypt + 7; i++) {
for (int j = mid - 5; j <= mid + 6; j++) {
if (j == mid && ct > 0) {
gra[i][j] = bullets.st[ct--];
}
else {
gra[i][j] = pt[i - rule / 2 - dy - dypt][j - mid + 5];
}
}
}
}
for (int i = 0; i < dy + rule + 7; i++) {
puts(gra[i]);
}
}
}game;
void* getMsg(void* f) {
game* t = (game*)f;
while (1) {
char click = '#';
t->ck();
click = getch();
t->click = click;
if (click == ' ') {
t->delt();
}
if (click == 'w' || click == 'W') {
t->fire();
}
if (click == 's' || click == 'S') {
t->getbullet();
}
if (t->win()) {
printf("恭喜你赢了!!!");
t->flag = 1;
break;
}
if (t->lost()) {
printf("别灰心再来一次!!!");
t->flag = 1;
break;
}
}
return NULL;
}
int main() {
begin:;
game s;
system("color 57");
int tt = 5;
char meau[12][35] = {
"*|******************************|*",
"*| |*",
"*| |*",
"*| |*",
"*| 开始游戏 |*",//4
"*| |*",
"*| |*",
"*| 退出游戏 |*",//7
"*| |*",
"*| (w s选择a选中)|*",
"*| |*",
"*|******************************|*",
};
int choose = 0;
char choos1[2][35] = { "*| >>>>>>>>>开始游戏<<<<<<<<<< |*" , "*| 开始游戏 |*" },
choos2[2][35] = { "*| >>>>>>>>>退出游戏<<<<<<<<<< |*", "*| 退出游戏 |*" };
char ch = ' ';
while (1) {
if (ch == 'a'|| ch == 'A') break;
if (ch == 'w' || ch == 'W'|| ch == 's' || ch == 'S') {
choose ^= 1;
}
system("cls");
if (choose == 0) {
strcpy(meau[4],choos1[0]);
strcpy(meau[7],choos2[1]);
}
else {
strcpy(meau[4], choos1[1]);
strcpy(meau[7], choos2[0]);
}
for (int i = 0; i <= 11; i++) {
puts(meau[i]);
}
ch = getch();
}
if (choose == 1) goto end;
s.innit(1);
while (tt--) {
system("cls");
printf("\n\n\n\n\n 全屏游戏更爽哦 \n 游戏将在 %d 秒后开始",tt);
Sleep(1000);
}
printf("\n\n\n\n\n《《《《《《《游戏开始》》》》》》》");
Sleep(1000);
//s.show();
for (int i = 0;; i++) {
//单位毫秒
Sleep(1000);
if (s.flag) {
break;
}
system("cls");
s.next();
s.show();
s.k.show();
if (s.win()) {
printf("恭喜你赢了!!!");
s.flag = 1;
break;
}
if (s.lost()) {
printf("别灰心再来一次!!!");
s.flag = 1;
break;
}
}
end:;
printf("游戏结束!!!");
Sleep(5000);
}
附:
游戏中或许有些 bug 还请帮忙更正