重磅消息,经过大概6小时的奋战,我用C语言实现了单色蜘蛛纸牌,当然了,因为我用的是结构体定义了牌的各项数据,如果再多加一项花色数据的话,就可以实现多色蜘蛛纸牌,然后再在判断里面加入异色不能相互链接就可以。我这次用的东西蛮多,指针、结构体都有用到。
他们说必须要用什么二叉树来实现这个,我却不信,所以我决定挑战一下,结果还不错,至少它没有很大的问题,其实这些小的bug 也可以修,但是我懒。
但是我有点累了,我不想花太多时间在这个东西上面,事实上我花费的时间已经超出我的预期了。我需要进一步的学习和新的知识、新的挑战,这个旧的项目就做到这里吧,或许一些太阳和月亮之后我会想把这个东西进一步完善,但是目前它就这样就可以了。
声明(提示):目前的这个版本是有微小bug的,但是不影响玩,基本上没有什么决定性的失误,但是确实有bug,比如我没有测试那个checkDone()函数是否能有效将完成的一组牌归零,因为我懒得把它玩到一列都完成。又比如移动牌能否移动到空列的那个判断是否有效,我觉得应该能行,但是也没有测试,因为我懒得玩玩到一整列都空掉。再比如明牌函数偶尔会明牌失败,但是你不要担心,因为它一般放着不动,过一两次移动之后还是可以自动明牌成功。原因未知。
现在我们展示“源.c”文件内的内容:
#include"TriPointC.h"
int main()
{
printf(" 欢迎尝试我设计的傻瓜版蜘蛛纸牌\n 我必须点明,J是纸牌里的10\n K是纸牌里的Q,L则是纸牌里的K\n 原因在于我的技术处理起来这样简单一点\n");
int i = 0; int t = 0;
int m = 0; int n = 0;
int vic = 0; int Ot = 0;
int sendCtrl = 0;
int* psend = &sendCtrl;
char arr[13][17] = { ' ' };
srand((unsigned int)time(NULL));
for (m = 0; m < 13; m++) {
for (n = 0; n < 17; n++) {
arr[m][n] = ' ';
}
}
struct Card CardPack[13][8];
IniCard(CardPack);
FirPlcCard(CardPack, arr);
while (vic == 0) {
ShowBoardFir(arr);
printf("请问是否需要发牌?需要请扣1,否则扣0:");
scanf("%d", &Ot);
if (Ot == 1&&sendCtrl!=5) {
sendOutCard(CardPack, arr,psend);
}
else if (Ot == 1 && sendCtrl == 5) {
printf("你已经耗光了余牌");
}
ShowBoardFir(arr);
//printf("%d", arr[3][5]);
MoveCard(CardPack, arr);
DTUCheckStar(arr, CardPack);
checkDone(arr);
//ShowBoardFir(arr);
}
return 0;
}
下面我们展示头文件“TriPointC.c”中的内容:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
struct Card
{
int num; int y;
int packnum;
int useif;
};
void IniCard(struct Card on1[13][8]);
void MoveCard(struct Card on2[13][8], char arr[13][17]);
void FirPlcCard(struct Card on2[13][8],char arr[13][17]);
void sendOutCard(struct Card on3[13][8],char arr[13][17],int* pr);
void ShowBoardFir(char arr[13][17]);
void DTUCheckStar(char arr[13][17], struct Card on3[13][8]);
int checkDCard(int x,int y,char arr[13][17]);
void checkDone(char arr[13][17]);
下面我们展示“TriPoint C.c”中的内容:
#include"TriPointC.h"
//初始化8副牌
void IniCard(struct Card on1[13][8]) {
int m = 0, n = 0;
int pack = 0;
while (pack < 8) {
for (m = 1; m < 13; m++) {
on1[m][pack].num = m;
on1[m][pack].useif = 0;
on1[m][pack].packnum = pack;
}
pack++;
}
}
//初次自动放牌
void FirPlcCard(struct Card on2[13][8],char arr[13][17]) {
int m = 0, n = 0; int t = 0; int pack = 0; int fin = 0;
for (n = 0; n < 5; n++) {
for (t = 0; t < 10; t++) {
m = rand() % 13;
pack = rand() % 8;
if (t > 3 && n == 4) {
if (on2[m][pack].useif == 0) {
if (on2[m][pack].num < 10) {
//printf("0%d ", on2[m][pack].num);
arr[t][n] = on2[m][pack].num + 48;
}
else {
//printf("%d ", on2[m][pack].num);
arr[t][n] = on2[m][pack].num + 64;
}
on2[m][pack].useif = 1;
}
else {
t--;
}
}
else if (on2[m][pack].useif == 0) {
if (on2[m][pack].num < 10) {
//printf(/*"0%d "*/"** "/*, on2[m][pack].num*/);
arr[t][n] = 42;
}
else {
//printf(/*"%d "*/"** "/*, on2[m][pack].num*/);
arr[t][n] = 42;
}
//on2[m][pack].useif = 1;
}
else {
t--;
}
}
//printf("\n");
}
/*t = 0; */
t--; n--;
//printf("t=%d and n=%d\n", t, n);
while (fin < 5) {
m = rand() % 13;
pack = rand() % 8;
if (on2[m][pack].useif == 0) {
if (on2[m][pack].num < 10) {
//printf("0%d ", on2[m][pack].num);
arr[t][n] = on2[m][pack].num+48;
t++;
if (t == 10) {
n++; t = 0;
}
}
else {
//printf("%d ", on2[m][pack].num);
arr[t][n] = on2[m][pack].num+64;
t++;
if (t == 10) {
n++; t = 0;
}
}
on2[m][pack].useif = 1;
}
else {
fin--;
}
fin++;
}
}
//再次派牌,一次十张
void sendOutCard(struct Card on3[13][8],char arr[13][17],int* pr) {
int m = 0, n = 0; int t = 0; int pack = 0; int num = 0;
for (m = 0; m < 12; m++) {
for (n = 16; n > 0; n--) {
num = rand() % 13; pack = rand() % 8;
if (arr[m][n] == ' ') {
}
else {
if (on3[num][pack].useif == 0) {
if (on3[num][pack].num < 10) {
arr[m][n + 1] = on3[num][pack].num + 48;
on3[num][pack].useif = 1;
break;
}
else {
arr[m][n + 1] = on3[num][pack].num + 64;
on3[num][pack].useif = 1;
break;
}
}
else {
n++;
}
}
}
}
*pr += 1;
}
//移动牌
int checkDCard(int x,int y,char arr[13][17]) {
int cont = y/*16 - y*/; int i = 1; int u = 0;
for (cont = y/*16 - y*/;cont < 16; cont++) {
if (arr[x][y+i] == ' ') {
if (i==1) {
u = 1;
}
break;
}
else {
if (arr[x][y + i] - arr[x][y+i-1] > 0) {
u = 100;
break;
}
else {
i++;
}
}
}
if (u==1||u==100) {
return u;
}
else {
return i;
}
}
void MoveCard(struct Card on2[13][8],char arr[13][17]) {
int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0;
int count = 0;
printf("请问要移动哪张牌:");
scanf("%d %d", &x1, &y1);
printf("收到,请问要移动到什么位置:");
scanf("%d %d", &x2, &y2);
if ((arr[x1][y1] < 77) && (arr[x1][y1]>48)) {
count=checkDCard(x1, y1, arr);
if (count == 100) {
printf("这个牌组不可以移动,请换其他牌移动");
}
else if (count == 1) {
//移动那一张牌
if (((arr[x2][y2 - 1] != ' ')&&(x1!=x2)&&(arr[x2][y2-1]==arr[x1][y1]+1))||(arr[x2][y2-1]==74&&arr[x1][y1]==57)) {
arr[x2][y2] = arr[x1][y1];
arr[x1][y1] = ' ';
}
else {
printf("这个位置不能移动\n");
MoveCard(on2, arr);
}
}
else {
if (((arr[x2][y2 - 1] != ' ') && (x1 != x2) && (arr[x2][y2 - 1] == arr[x1][y1] + 1))|| (arr[x2][y2 - 1] == 74 && arr[x1][y1] == 57)) {
while (count >= 0) {
arr[x2][y2+count] = arr[x1][y1+count];
arr[x1][y1+count] = ' ';
count--;
}
}
else if (y2 == 0) {
while (count >= 0) {
arr[x2][y2 + count] = arr[x1][y1 + count];
arr[x1][y1 + count] = ' ';
count--;
}
}
}
}
else{
/* if (arr[x1][y1] == 0 || arr[x1][y1] == 42)*/
printf("这个位置无法移动,请换一个吧\n");
MoveCard(on2, arr);
}
}
//第一次(或许可以改成普遍的展示牌)
void ShowBoardFir(char arr[13][17]) {
int t = 0; int u = 0;
for (t = 0; t < 17; t++) {
for (u = 0; u < 10; u++) {
printf("%c ", arr[u][t]);
}
printf("\n");
}
/*for (u = 0; u < 4; u++) {
printf("%c ", arr[u][5]);
}*/
}
//从下到上检查每一列的牌是否有明牌,如果全是暗牌那么将最下方暗牌改成明牌
void DTUCheckStar(char arr[13][17], struct Card on3[13][8]) {
int x = 7; int y = 0; int tr = 0;
int ver = 7; int Number1 = 0; int Number2 = 0;
for (y = 0; y < 10; y++) {
for (x = 7; x >= 0; x--) {
if (arr[y][x] < 77 && arr[y][x]>48) {
tr++;
}
}
if (tr == 0) {
for (ver = 7; ver >= 0; ver--) {
if (arr[y][ver] != 42) {
}
else {
break;
}
}
Number1 = rand() % 13; Number2 = rand() % 8;
if (on3[Number1][Number2].useif == 0) {
if (on3[Number1][Number2].num < 10) {
arr[y][ver] = on3[Number1][Number2].num + 48;
on3[Number1][Number2].useif = 1;
break;
}
else {
arr[y][ver] = on3[Number1][Number2].num + 64;
on3[Number1][Number2].useif = 1;
break;
}
}
else {
ver++;
}
}
tr = 0;
}
}
/*
*
*
L
K
J
9
8
7
6
5
4
3
2
1
*/
void checkDone(char arr[13][17]) {
int x = 0; int y = 16; int sum = 0; int i = 0;
for (x = 0; x < 13; x++) {
for (y = 16; y >= 0; y--) {
if (arr[x][y] == ' ') {
}
else if (arr[x][y] < 77 && arr[x][y]>48) {
if (arr[x][y - 1] > arr[x][y]) {
sum++;
}
/*else if ((arr[x][y] < 77 && arr[x][y]>48) && (arr[x][y - 1] == 42)) {
sum++;
}*/
else {
if (sum == 12) {
break;
}
else {
sum = 0;
}
}
}
else {
break;
}
}
if (sum == 12) {
while (sum > 0) {
arr[x][y + i] = ' ';
i++;
sum--;
}
}
}
}
我这次罕见的给它写了注释,因为我是一边写一边改的类型,最开始我是没有写注释的,直到我开始写判断函数checkDone()的时候,我觉得有必要加上注释以防止过去很多日子之后我搞不清楚它到底是个什么东西。
我这会仍然采用了多文件的书写方法,以方便你生成.lib文件。
我会尝试上传这个项目的exe文件,如果成功的话你可以直接下载来玩。顺便一提,我会上传那三个文件,如果你把前面的注释取消,后面的加上注释,你就可以得到三子棋、五子棋。扫雷在另一个文件里面,因此你得不到扫雷。
如果你游玩过程中发现新的我没有提及的bug,请务必私信联络我!
以及我必须对玩法给你一个提示,横着数从左到右分别是0-9,纵着数从上到下分别是0-16,先输入横坐标再输入纵坐标。我其实可以直接用一个printf说明这个事情,但是你猜怎么着,太累了,毁灭吧。