3-1
练习3-1编写一个程序,把List3-9程序中的函数count_no和disp_result整合成一个函数,然后讨论更改前和更改后的程序。
//List 3-9
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
char *hd[] = {"石头", "剪刀", "布"}; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp = rand() % 3; /* 用随机数生成计算机的手势(0~2) */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++)
printf("(%d)%s ", i, hd[i]);
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 计数胜利/失败/平局次数 */
void count_no(int result) {
switch (result) {
case 0: draw_no++; break;
case 1: lose_no++; break;
case 2: win_no++; break;
}
}
/* 显示判断结果 */
void disp_result(int result) {
switch (result) {
case 0: puts("平局。"); break;
case 1: puts("你输了。"); break;
case 2: puts("你赢了。"); break;
}
}
/* 确认是否再次挑战 */
int confirm_retry(void) {
int x;
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &x);
return x;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
count_no(judge); /* 更新胜利/失败/平局次数 */
disp_result(judge); /* 显示判断结果 */
retry = confirm_retry(); /* 确认是否再次挑战 */
} while (retry == 1);
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
//答案
#define _CRT_SECURE_NO_WARNINGS 1
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp = rand() % 3; /* 用随机数生成计算机的手势(0~2) */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++)
printf("(%d)%s ", i, hd[i]);
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 确认是否再次挑战 */
int confirm_retry(void) {
int x;
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &x);
return x;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
retry = confirm_retry(); /* 确认是否再次挑战 */
} while (retry == 1);
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
更改前:
模块化清晰:原始程序中,count_no 和 disp_result 分别负责不同的功能,职责单一,模块化清晰。
可维护性高:单独的函数使得每个函数更容易维护和修改。
更改后:
简化结构:整合后的函数减少了函数调用的次数,使代码更加简洁。
功能合并:合并后的函数使得逻辑更加集中,不需要在不同函数间跳转。
总体来说: 更改后的程序更加简洁,但在某些情况下,过度简化可能会降低代码的可维护性和可读性。在实际开发中,应根据具体情况选择合适的方案。
3-2
把List3-10中的猜赢3次拳泛化为猜赢n次拳。在游戏一开始就问“要猜赢几次?”,让玩家来输人n的值。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int target_wins; /* 目标胜利次数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
/* 询问目标胜利次数 */
printf("要猜赢几次?");
scanf("%d", &target_wins);
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp = rand() % 3; /* 用随机数生成计算机的手势(0~2) */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
int main(void) {
int judge; /* 胜负 */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
} while (win_no < target_wins && lose_no < target_wins);
printf(win_no == target_wins ? "\n你赢了。\n" : "\n我赢了。\n");
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
3-3
编写一个“猜拳游戏”,让计算机只能出石头和布
因为计算机只能出石头和布,而且控制手势的数组是char *hd[] = {"石头", "剪刀", "布"};
,所以,只能让计算机生成 0和2,我们可以按照下面的代码来控制:
comp = rand() % 2 * 2; /* 生成0(石头)或2(布) */
这样 com
就只会生成 0和2 了。
完整代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
const
char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp = (rand() % 2) * 2; /* 生成0(石头)或2(布) */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 确认是否再次挑战 */
int confirm_retry(void) {
int x;
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &x);
return x;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
retry = confirm_retry(); /* 确认是否再次挑战 */
} while (retry == 1);
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
3-4
编写一个“猜拳游戏”,让计算机第1次一定出石头。
※让计算机从第2次开始随机出石头、剪刀或者布。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
if (round_no == 0) {
comp = 0; /* 第1次一定出石头 */
}
else {
comp = rand() % 3; /* 从第2次开始随机生成手势(0, 1, 2) */
}
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 确认是否再次挑战 */
int confirm_retry(void) {
int x;
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &x);
return x;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
round_no++; /* 增加轮数 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
retry = confirm_retry(); /* 确认是否再次挑战 */
} while (retry == 1);
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
3-5
编写一个“猜拳游戏”,让计算机每5次就会“后出”编写两个版本,一个是只要玩家愿意就能不断重复玩的“猜拳游戏”,另一个是猜赢n次就会结束的“猜拳游戏”。
//版本一
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
const
char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
if (round_no % 5 == 4) {
printf("请你先出:\n");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
comp = rand() % 3; /* 随机生成计算机手势 */
}
else {
comp = rand() % 3; /* 随机生成计算机手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 确认是否再次挑战 */
int confirm_retry(void) {
int x;
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &x);
return x;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
round_no++; /* 增加轮数 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
retry = confirm_retry(); /* 确认是否再次挑战 */
} while (retry == 1);
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
//版本二
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
int target_wins; /* 目标胜利次数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
/* 询问目标胜利次数 */
printf("要猜赢几次?");
scanf("%d", &target_wins);
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
if (round_no % 5 == 4) {
printf("请你先出:\n");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
comp = rand() % 3; /* 随机生成计算机手势 */
}
else {
comp = rand() % 3; /* 随机生成计算机手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
int main(void) {
int judge; /* 胜负 */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
round_no++; /* 增加轮数 */
/* 显示计算机和玩家的手势 */
printf("我出%s,你出%s。\n", hd[comp], hd[human]);
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
} while (win_no < target_wins && lose_no < target_wins);
printf(win_no == target_wins ? "\n你赢了。\n" : "\n我赢了。\n");
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
3-6
编写一个“猜拳游戏”,让游戏结束时显示玩家和计算机出过的所有手势和胜负的历史记录。
编写两个版本,一个是只要玩家愿意就能不断重复玩的“猜拳游戏”,另一个是猜赢n次就会结束的“猜拳游戏”。
※关于历史记录的保存可参见第5章。
//版本一
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROUNDS 1000 /* 最大记录轮数 */
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
char *hd[] = {"石头", "剪刀", "布"}; /* 手势 */
int human_history[MAX_ROUNDS]; /* 保存玩家手势 */
int comp_history[MAX_ROUNDS]; /* 保存计算机手势 */
int result_history[MAX_ROUNDS]; /* 保存胜负记录 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
if (round_no % 5 == 4) {
printf("请你先出:\n");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
comp = rand() % 3; /* 随机生成计算机手势 */
} else {
comp = rand() % 3; /* 随机生成计算机手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 记录历史 */
void record_history(int human, int comp, int result) {
if (round_no < MAX_ROUNDS) {
human_history[round_no] = human;
comp_history[round_no] = comp;
result_history[round_no] = result;
}
}
/* 显示历史记录 */
void display_history(void) {
printf("\n历史记录:\n");
for (int i = 0; i < round_no; i++) {
printf("第%d轮:你出%s,我出%s -> %s\n",
i + 1, hd[human_history[i]], hd[comp_history[i]],
result_history[i] == 0 ? "平局" : (result_history[i] == 1 ? "你输了" : "你赢了"));
}
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
record_history(human, comp, judge); /* 记录历史 */
round_no++; /* 增加轮数 */
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &retry);
} while (retry == 1);
display_history(); /* 显示历史记录 */
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
//版本二
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROUNDS 1000 /* 最大记录轮数 */
int human; /* 玩家手势 */
int comp; /* 计算机手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
int target_wins; /* 目标胜利次数 */
const char *hd[] = {"石头", "剪刀", "布"}; /* 手势 */
int human_history[MAX_ROUNDS]; /* 保存玩家手势 */
int comp_history[MAX_ROUNDS]; /* 保存计算机手势 */
int result_history[MAX_ROUNDS]; /* 保存胜负记录 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
/* 询问目标胜利次数 */
printf("要猜赢几次?");
scanf("%d", &target_wins);
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
if (round_no % 5 == 4) {
printf("请你先出:\n");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
comp = rand() % 3; /* 随机生成计算机手势 */
} else {
comp = rand() % 3; /* 随机生成计算机手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 记录历史 */
void record_history(int human, int comp, int result) {
if (round_no < MAX_ROUNDS) {
human_history[round_no] = human;
comp_history[round_no] = comp;
result_history[round_no] = result;
}
}
/* 显示历史记录 */
void display_history(void) {
printf("\n历史记录:\n");
for (int i = 0; i < round_no; i++) {
printf("第%d轮:你出%s,我出%s -> %s\n",
i + 1, hd[human_history[i]], hd[comp_history[i]],
result_history[i] == 0 ? "平局" : (result_history[i] == 1 ? "你输了" : "你赢了"));
}
}
int main(void) {
int judge; /* 胜负 */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
judge = (human - comp + 3) % 3; /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
record_history(human, comp, judge); /* 记录历史 */
round_no++; /* 增加轮数 */
} while (win_no < target_wins && lose_no < target_wins);
display_history(); /* 显示历史记录 */
printf(win_no == target_wins ? "\n你赢了。\n" : "\n我赢了。\n");
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
3-7
练习3-7编写一个3人对战的“猜拳游戏”。由计算机来担任2个角色,这2个角色的手势都用随机数来生成。
编写两个版本,一个是只要玩家愿意就能不断重复玩的“猜拳游戏”,另一个是猜赢n次就会结束的“猜拳游戏”。
//版本一
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROUNDS 1000 /* 最大记录轮数 */
int human; /* 玩家手势 */
int comp1; /* 计算机1手势 */
int comp2; /* 计算机2手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
int human_history[MAX_ROUNDS]; /* 保存玩家手势 */
int comp1_history[MAX_ROUNDS]; /* 保存计算机1手势 */
int comp2_history[MAX_ROUNDS]; /* 保存计算机2手势 */
int result_history[MAX_ROUNDS]; /* 保存胜负记录 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp1 = rand() % 3; /* 随机生成计算机1手势 */
comp2 = rand() % 3; /* 随机生成计算机2手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 记录历史 */
void record_history(int human, int comp1, int comp2, int result) {
if (round_no < MAX_ROUNDS) {
human_history[round_no] = human;
comp1_history[round_no] = comp1;
comp2_history[round_no] = comp2;
result_history[round_no] = result;
}
}
/* 显示历史记录 */
void display_history(void) {
printf("\n历史记录:\n");
for (int i = 0; i < round_no; i++) {
printf("第%d轮:你出%s,计算机1出%s,计算机2出%s -> %s\n",
i + 1, hd[human_history[i]], hd[comp1_history[i]], hd[comp2_history[i]],
result_history[i] == 0 ? "平局" : (result_history[i] == 1 ? "你输了" : "你赢了"));
}
}
/* 判断三者之间的胜负 */
int judge_result(int human, int comp1, int comp2) {
if (human == comp1 && comp1 == comp2) {
return 0; // 平局
}
int win = 0, lose = 0;
if(comp2 == comp1&& (human - comp2 + 3) % 3 == 2) return 2;
if (comp2 == comp1 && (human - comp2 + 3) % 3 == 1) return 1;
if (human == comp1 && (human - comp2 + 3) % 3 == 2) return 2;
if (human == comp1 && (human - comp2 + 3) % 3 == 1) return 1;
if (human == comp2 && (human - comp1 + 3) % 3 == 2) return 2;
if (human == comp2 && (human - comp1 + 3) % 3 == 1) return 1;
return 0;
}
int main(void) {
int judge; /* 胜负 */
int retry; /* 再来一次? */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
judge = judge_result(human, comp1, comp2); /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
record_history(human, comp1, comp2, judge); /* 记录历史 */
round_no++; /* 增加轮数 */
printf("再来一次吗...(0)否(1)是:");
scanf("%d", &retry);
} while (retry == 1);
display_history(); /* 显示历史记录 */
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}
//版本二
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROUNDS 1000 /* 最大记录轮数 */
int human; /* 玩家手势 */
int comp1; /* 计算机1手势 */
int comp2; /* 计算机2手势 */
int win_no; /* 胜利次数 */
int lose_no; /* 失败次数 */
int draw_no; /* 平局次数 */
int round_no; /* 游戏轮数 */
int target_wins; /* 目标胜利次数 */
const char* hd[] = { "石头", "剪刀", "布" }; /* 手势 */
int human_history[MAX_ROUNDS]; /* 保存玩家手势 */
int comp1_history[MAX_ROUNDS]; /* 保存计算机1手势 */
int comp2_history[MAX_ROUNDS]; /* 保存计算机2手势 */
int result_history[MAX_ROUNDS]; /* 保存胜负记录 */
/* 初始处理 */
void initialize(void) {
win_no = 0; /* 胜利次数 */
lose_no = 0; /* 失败次数 */
draw_no = 0; /* 平局次数 */
round_no = 0; /* 游戏轮数 */
srand(time(NULL)); /* 设定随机数种子 */
printf("猜拳游戏开始!\n");
/* 询问目标胜利次数 */
printf("要猜赢几次?");
scanf("%d", &target_wins);
}
/* 运行猜拳游戏(读取/生成手势) */
void jyanken(void) {
int i;
comp1 = rand() % 3; /* 随机生成计算机1手势 */
comp2 = rand() % 3; /* 随机生成计算机2手势 */
do {
printf("\n\a石头剪刀布...");
for (i = 0; i < 3; i++) {
printf("(%d)%s ", i, hd[i]);
}
printf(": ");
scanf("%d", &human); /* 读取玩家的手势 */
} while (human < 0 || human > 2);
}
/* 更新和显示结果 */
void update_and_display_result(int result) {
switch (result) {
case 0:
draw_no++;
puts("平局。");
break;
case 1:
lose_no++;
puts("你输了。");
break;
case 2:
win_no++;
puts("你赢了。");
break;
}
}
/* 记录历史 */
void record_history(int human, int comp1, int comp2, int result) {
if (round_no < MAX_ROUNDS) {
human_history[round_no] = human;
comp1_history[round_no] = comp1;
comp2_history[round_no] = comp2;
result_history[round_no] = result;
}
}
/* 显示历史记录 */
void display_history(void) {
printf("\n历史记录:\n");
for (int i = 0; i < round_no; i++) {
printf("第%d轮:你出%s,计算机1出%s,计算机2出%s -> %s\n",
i + 1, hd[human_history[i]], hd[comp1_history[i]], hd[comp2_history[i]],
result_history[i] == 0 ? "平局" : (result_history[i] == 1 ? "你输了" : "你赢了"));
}
}
/* 判断三者之间的胜负 */
int judge_result(int human, int comp1, int comp2) {
if (human == comp1 && comp1 == comp2) {
return 0; // 平局
}
if (comp2 == comp1 && (human - comp2 + 3) % 3 == 2) return 2;
if (comp2 == comp1 && (human - comp2 + 3) % 3 == 1) return 1;
if (human == comp1 && (human - comp2 + 3) % 3 == 2) return 2;
if (human == comp1 && (human - comp2 + 3) % 3 == 1) return 1;
if (human == comp2 && (human - comp1 + 3) % 3 == 2) return 2;
if (human == comp2 && (human - comp1 + 3) % 3 == 1) return 1;
return 0;
}
int main(void) {
int judge; /* 胜负 */
initialize(); /* 初始处理 */
do {
jyanken(); /* 运行猜拳游戏 */
judge = judge_result(human, comp1, comp2); /* 判断胜负 */
update_and_display_result(judge); /* 更新和显示结果 */
record_history(human, comp1, comp2, judge); /* 记录历史 */
round_no++; /* 增加轮数 */
} while (win_no < target_wins);
display_history(); /* 显示历史记录 */
printf("%d胜 %d负 %d平。\n", win_no, lose_no, draw_no);
return 0;
}