C语言小游戏
0、前言
1、我使用的是编译软件是vc6.0
2、如果代码无法运行,你可以尝试吧文件xxx.c改为xxx.cpp
3、四个小游戏我都运行过,确保是可以运行的。虽然可玩性、操作性。。。
1、普普通通的五子棋
这是四个游戏中,个人感觉最好的一个了。
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include <stdlib.h>
#define N 65
int status[N][N]={{0},{0}};//记录棋盘情况,0无,1红棋/玩家,2为白棋/电脑
int flag=0;//判断输赢
int direct[2];//方向
int Value1[N][N]={{0},{0}};//计算权值
int Value2[N][N]={{0},{0}};//计算权值
int regrex,regrey,regrex1,regrey1;
int count=0;//计算棋子数量
void chess_board();//打印棋盘
void red_movexy();//红子棋移动光标
void white_movexy();//白棋移动光标
void red_chess(int x,int y);//红棋
void white_chess(int x,int y);//白棋
void man_man();
void man_machine();//人机对战
int judge_chess(int x,int y);//判断这个位置是否下过
int judge_winner(int x,int y,int temp);//判断输赢
void machine_attack();//电脑进攻权值
void machine_defend();//电脑防守权值
void find_position();//寻找最佳权值
void Regret();//悔棋函数
void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄
SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色
}
void gotoxy(int x, int y) //光标函数
{
HANDLE handle;
COORD coord; //获取坐标轴结构体
coord.X = x;
coord.Y = y;
handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11
SetConsoleCursorPosition(handle, coord); //移动光标到x,y处
}
void chess_board()//打印棋盘
{
int i,j;
for(i=0;i<=30;i++)
for(j=0;j<=60;j+=4)
{
gotoxy(j,i);
printf("|");
}
for(i=0;i<=30;i+=2)
for(j=1;j<=57;j+=4)
{
gotoxy(j,i);
printf("---");
}
}
void chess_menu()//打印棋盘旁的菜单
{
int i,j;
for(i=1;i<=29;i++)
{
gotoxy(67,i);
printf("||");
}
for(i=1;i<=29;i++)
{
gotoxy(89,i);
printf("||");
}
gotoxy(69,1);
printf("--------------------");
gotoxy(69,29);
printf("--------------------");
gotoxy(75,3);
printf("模 式");
gotoxy(75,20);
printf("提 示");
}
void red_movexy()//红棋移动光标
{
loop2:gotoxy(direct[0],direct[1]);
char key='y';
int temp;
while(key!=' ')
{
key=getch();
switch(key)
{
case 'W':
case 'w':
direct[1]-=2;
if(direct[1]<=1)
direct[1]=1;
break;
case 's':
case 'S':
direct[1]+=2;
if(direct[1]>=29)
direct[1]=29;
break;
case 'a':
case 'A':
direct[0]-=4;
if(direct[0]<=2)
direct[0]=2;
break;
case 'd':
case 'D':
direct[0]+=4;
if(direct[0]>=58)
direct[0]=58;
break;
case 'q':
case 'Q':
{
int message=MessageBox(NULL,"是否确定悔棋?","友情提示",MB_OKCANCEL);
if(IDCANCEL==message)
break;
if(IDOK==message)
{
Regret();
break;
}
}
}
gotoxy(direct[0],direct[1]);
}
temp=judge_chess(direct[1],direct[0]);
if(temp==1)
{
gotoxy(70,22);
BackGround(4, 0);
printf("这里已经被人下过了");
goto loop2;
}
}
void white_movexy()//白棋移动光标
{
loop1:gotoxy(direct[0],direct[1]);
char key='y';
int temp;
while(key!='0')
{
key=getch();
switch(key)
{
case 72:
direct[1]-=2;
if(direct[1]<=1)
direct[1]=1;
break;
case 80:
direct[1]+=2;
if(direct[1]>=29)
direct[1]=29;
break;
case 75:
direct[0]-=4;
if(direct[0]<=2)
direct[0]=2;
break;
case 77:
direct[0]+=4;
if(direct[0]>=58)
direct[0]=58;
break;
case 'B':
case 'b':
{
int message=MessageBox(NULL,"是否确定悔棋?","友情提示",MB_OKCANCEL);
if(IDCANCEL==message)
break;
if(IDOK==message)
{
Regret();
break;
}
}
}
gotoxy(direct[0],direct[1]);
}
temp=judge_chess(direct[1],direct[0]);
if(temp==1)
{
gotoxy(70,22);
BackGround(4, 0);
printf("这里已经被人下过了");
goto loop1;
}
}
void red_chess(int x,int y)//打印红棋
{
BackGround(4,0);
regrex=x;//记录上一落子的位置 ,方便悔棋
regrey=y;
count++;
printf("●");
status[x][y]=1;
}
void white_chess(int x,int y)//打印白棋
{
BackGround(7,0);
regrex1=x;
regrey1=y;
printf("●");
count++;
status[x][y]=2;
}
void machine_chess(int x,int y)//电脑落子
{
BackGround(7,0);
status[x][y]=2;
regrex1=x;
regrey1=y;
count++;
gotoxy(y,x);
printf("●");
}
int judge_chess(int x,int y)//判断这个地方是否有棋子
{
if(status[x][y]==0)
return 0;
else
return 1;
}
int judge_winner(int x,int y,int temp)//判断输赢
{
int i,j,n1,n2;
n1=n2=0;
for(i=x,j=y+4;j<=58;j+=4)//右
{
if(status[i][j]==temp)
n1++;
else
break;
}
for(i=x,j=y;j>=2;j-=4)//左
{
if(status[i][j]==temp)
n2++;
else
break;
}
if(n1+n2>=5)
return temp;
n1=n2=0;
for(i=x,j=y;i>=1;i-=2)//上
{
if(status[i][j]==temp)
n1++;
else
break;
}
for(i=x+2,j=y;i<=30;i+=2)//下
{
if(status[i][j]==temp)
n2++;
else
break;
}
if(n1+n2>=5)
return temp;
n1=n2=0;
for(i=x-2,j=y+4;i>=1&&j<=58;i-=2,j+=4)//右上
{
if(status[i][j]==temp)
n1++;
else
break;
}
for(i=x,j=y;i<=30&&j>=2;i+=2,j-=4)//左下
{
if(status[i][j]==temp)
n2++;
else
break;
}
if(n1+n2>=5)
return temp;
n1=n2=0;
for(i=x,j=y;i>=0&&j>=0;i-=2,j-=4)//左上
{
if(status[i][j]==temp)
n1++;
else
break;
}
for(i=x+2,j=y+4;i<=30&&j<=58;i+=2,j+=4)//右下
{
if(status[i][j]==temp)
n2++;
else
break;
}
if(n1+n2>=5)
return temp;
return 0;
}
void machine_attack()//电脑进攻权值
{
int i1,j1;
int k1,k2,k;
for(int i=1;i<=30;i+=2)
{
for(int j=2;j<=58;j+=4)
{
if(status[i][j])
Value1[i][j]=0;
if(status[i][j]==0)
{
k1=k2=0;
for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找电脑棋子数
{
if(status[i1][j1]==2)
k1++;
else
break;
}
for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找电脑棋子数
{
if(status[i1][j1]==2)
k2++;
else
break;
}
k=k1>k2? k1:k2;
k1=k2=0;
for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找电脑棋子数
{
if(status[i1][j1]==2)
k1++;
else
break;
}
for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找电脑棋子数
{
if(status[i1][j1]==2)
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1? k:k1;
k1=k2=0;
for(i1=i-2,j1=j-4;i1>=0&&j1>=0;i1-=2,j1-=4)//往左上数寻找电脑棋子数
{
if(status[i1][j1]==2)
k1++;
else
break;
}
for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找电脑棋子数
{
if(status[i1][j1]==2 )
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1?k:k1;
k1=k2=0;
for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找电脑棋子数
{
if(status[i1][j1]==2)
k1++;
else
break;
}
for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找电脑棋子数
{
if(status[i1][j1]==2)
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1?k:k1;
switch(k)
{
case 3:
Value1[i][j]=15;break;
case 4:
Value1[i][j]=25;break;
default:
Value1[i][j]=3+2*k;break;
}
}
}
}
}
void machine_defend()//防守权值
{
int i1, j1;
int k1,k2,k;
for(int i=1;i<=30;i+=2)
{
for(int j=2;j<=58;j+=4)
{
if(status[i][j])
Value2[i][j]=0;
if(status[i][j]==0)
{
k1=k2=0;
for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找玩家棋子数
{
if(status[i1][j1]==1)
k1++;
else
break;
}
for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找玩家棋子数
{
if(status[i1][j1]==1)
k2++;
else
break;
}
k=k1>k2? k1:k2;
k1=k2=0;
for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找玩家棋子数
{
if(status[i1][j1]==1)
k1++;
else
break;
}
for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找玩家棋子数
{
if(status[i1][j1]==1)
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1?k:k1;
k1=k2=0;
for(i1=i-2,j1=j-4;i1>=1&&j1>=2;i1-=2,j1-=4)//往左上数寻找玩家棋子数
{
if(status[i1][j1]==1)
k1++;
else
break;
}
for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找玩家棋子数
{
if(status[i1][j1]==1)
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1?k:k1;
k1=k2=0;
for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找玩家棋子数
{
if(status[i1][j1]==1)
k1++;
else
break;
}
for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找玩家棋子数
{
if(status[i1][j1]==1)
k2++;
else
break;
}
k1=k1>k2? k1:k2;
k=k>k1?k:k1;
switch(k)
{
case 3:
Value2[i][j]=10;break;
case 4:
Value2[i][j]=20;break;
default:
Value2[i][j]=2+k*2;
}
}
}
}
}
void find_position()//找到最有价值的位置
{
int k1=0, k2=0;
int i, j, max=0;
for( i=1;i<=30;i+=2)
for( j=2;j<=58;j+=4)
{
if(max<=Value1[i][j])
{
max=Value1[i][j];
k1=i;
k2=j;
}
}
for( i=1;i<=30;i+=2)
for( j=2;j<=58;j+=4)
{
if(max<=Value2[i][j])
{
max=Value2[i][j];
k1=i;
k2=j;
}
}
direct[1]=k1; //将找到的位置传给光标
direct[0]=k2;
}
void man_man()//人人对战模式
{
loop5:system("cls");
char key;
int control;
gotoxy(2, 3);
printf("1.红 子 先 手");
gotoxy(2, 5);
printf("2.白 子 先 手");
gotoxy(2, 7);
printf("(输入相应序号选择)");
key=getch();
system("cls");
if(key=='1')
control=1;
else if(key=='2')
control=-1;
else
goto loop5;
gotoxy(70,5);
printf(" 人 人 对 战 ");
direct[1]=15;
direct[0]=30;
chess_board();
chess_menu();
while(flag==0)
{
if(control==1)
{
gotoxy(70,22);
BackGround(6,0);
printf(" 红 子 执 手 ");
red_movexy();
red_chess(direct[1],direct[0]);
flag=judge_winner(direct[1],direct[0],1);
}
else
{
gotoxy(70,22);
BackGround(6,0);
printf(" 白 子 执 手 ");
white_movexy();
white_chess(direct[1],direct[0]);
flag=judge_winner(direct[1],direct[0],2);
}
control=-control;
}
if(flag==1)
{
BackGround(7,0);
MessageBox(NULL,"游戏结束,红子胜利","五子棋游戏",MB_OK);
}
if(flag==2)
{
MessageBox(NULL,"游戏结束,白子胜利","五子棋游戏",MB_OK);
}
if(count>=225)
{
MessageBox(NULL,"游戏结束,平局","五子棋游戏",MB_OK);
}
}
void man_machine()//人机对战模式
{
loop6:system("cls");
char key;
int control;
gotoxy(2, 3);
printf("1.玩 家 先 手(玩家为红子)");
gotoxy(2, 5);
printf("2.电 脑 先 手(电脑为白子)");
gotoxy(2, 7);
printf("(输入相应序号选择)");
key=getch();
system("cls");
if(key=='1')
control=1;
else if(key=='2')
{
control=1;
machine_chess(13,26);
}
else
goto loop6;
gotoxy(70,5);
printf(" 人 机 对 战 ");
direct[1]=15;
direct[0]=30;
chess_board();
chess_menu();
while(flag==0)
{
if(control==1)
{
gotoxy(70,22);
BackGround(6,0);
printf(" 玩 家 执 手 ");
red_movexy();
red_chess(direct[1],direct[0]);
flag=judge_winner(direct[1],direct[0],1);
}
else
{
gotoxy(70,22);
BackGround(6,0);
printf(" 电 脑 执 手 ");
machine_defend();
machine_attack();
find_position();
machine_chess(direct[1],direct[0]);
flag=judge_winner(direct[1],direct[0],2);
}
control=-control;
}
gotoxy(8,18);
if(flag==1)
{
BackGround(7,0);
MessageBox(NULL,"太厉害了,您竟然战胜了电脑!","五子棋游戏",MB_OK);
}
if(flag==2)
{
MessageBox(NULL,"游戏结束,您输给了电脑","五子棋游戏",MB_OK);
}
if(count>=225)
{
MessageBox(NULL,"平局","五子棋游戏",MB_OK);
}
}
void Regret()//悔棋函数
{
gotoxy(regrey,regrex);
BackGround(0,0);
printf(" ");
status[regrex][regrey]=0;
gotoxy(regrey1,regrex1);
BackGround(0,0);
printf(" ");
status[regrex1][regrey1]=0;
count-=2;
}
void welcome()//游戏菜单
{
int k;
char choose;
system("cls");
for(k=2;k<=16;k+=2)//游戏菜单
{
gotoxy(5,k);
printf("|-----------------|");
}
gotoxy(5, 3);
printf("| 五 子 棋 游 戏 |");
gotoxy(5, 5);
printf("| 菜 单 |");
gotoxy(5, 7);
printf("| 1.人 人 对 战 |");
gotoxy(5, 9);
printf("| 2.人 机 对 战 |");
gotoxy(5, 11);
printf("| 3.游 戏 帮 助 |");
gotoxy(5, 13);
printf("| 4.更 新 日 志 |");
gotoxy(5, 15);
printf("| 5.退 出 游 戏 |");
gotoxy(5, 18);
printf("温馨提示:输入菜单对应序号进行操作");
gotoxy(5, 20);
printf("祝您游戏愉快!");
gotoxy(13, 20);
}
char Gametips()//游戏帮助
{
char choose;
int key;
system("cls");
gotoxy(2, 3);
printf("游戏操作:");
gotoxy(4, 5);
printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋");
gotoxy(4, 7);
printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋");
gotoxy(2, 19);
printf("(按任意键返回)");
return getch();
}
char Updatediary()//更新日志
{
system("cls");
gotoxy(2, 3);
printf("(暂时没有)");
gotoxy(2, 5);
printf("(按任意键返回)");
return getch();
}
int main()
{
system("title 五子棋");
system("mode con cols=92 lines=33");
char choose,temp;
thetop: loop:welcome();
choose=getch();
switch(choose)
{
case '1':
man_man();
goto thetop;
break;
case '2':
man_machine();
goto thetop;
break;
case '3':
temp=Gametips();
goto thetop;
break;
case '4':
temp=Updatediary();
goto thetop;
break;
case '5':
int message=MessageBox(NULL,"是否退出?","友情提示",MB_OKCANCEL);
if(IDCANCEL==message)
goto thetop;
if(IDOK==message)
{
break;
}
}
}
2、好难操作的贪吃蛇
贪吃蛇的基本框架还是有的。
文件一:stdafx.h
#if !defined(AFX_STDAFX_H__20B660F3_64B9_4993_8071_269F806FAF71__INCLUDED_)
#define AFX_STDAFX_H__20B660F3_64B9_4993_8071_269F806FAF71__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
代码二:主程序
#include "stdafx.h"
/*******头 文 件*******/
#include<stdio.h> //标准输入输出函数库
#include<time.h> //用于获得随机数
#include<windows.h> //控制dos界面
#include<stdlib.h> //即standard library标志库头文件,里面定义了一些宏和通用工具函数
#include<conio.h> //接收键盘输入输出
/*******宏 定 义*******/
#define U 1
#define D 2
#define L 3
#define R 4 //蛇的状态,U:上 ;D:下;L:左 R:右
/*******定 义 全 局 变 量 *******/
typedef struct snake //蛇身的一个节点
{
int x; //节点x坐标
int y; //节点y坐标
struct snake *next; //蛇身体下一节点
}snake;
int score=0; //总得分
int add=10; //每次吃食物得分
int HighScore = 0; //最高分
int status; //蛇前进状态
int sleeptime=200; //每次运行的时间间隔
snake *head; //蛇头指针
snake *food; //食物指针
snake *q; //遍历蛇的时候用到的指针
int endgamestatus=0; //游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏
HANDLE hOut; //控制台句柄
/*******函 数 声 明 *******/
void gotoxy(int x,int y); //设置光标位置
int color(int c); //更改文字颜色
void printsnake(); //字符画
void welcometogame(); //开始界面
void createMap(); //绘制地图
void scoreandtips(); //游戏界面右侧的得分和小提示
void initsnake(); //初始化蛇身,画蛇身
void createfood(); //创建并随机出现食物
int biteself(); //判断是否咬到了自己
void cantcrosswall(); //设置蛇撞墙的情况
void speedup(); //加速
void speeddown(); //减速
void snakemove(); //控制蛇前进方向
void keyboardControl(); //控制键盘按键
void Lostdraw(); //游戏结束界面
void endgame(); //游戏结束
void choose(); //游戏失败之后的选择
void File_out(); //在文件中读取最高分
void File_in(); //储存最高分进文件
void explation(); //游戏说明
/*
设置光标位置
*/
void gotoxy(int x,int y)
{
COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
/*
文字颜色函数
*/
int color(int c)
{
//SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色
return 0;
}
/*
字符拼成英文图案
*/
void printsnake()
{
color(2);
printf(" \n");
printf(" __________ ___ \n");
printf(" / \\ / \\ \\ |____ __\\__ \n");
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
printf(" | | |__| _/_ |_| / [|] |/ \n");
printf(" | | | | | / _|_ \\__/ \n");
printf(" \\ \\_______ / \\ |___/ ____ \n");
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
}
/*
开始界面
*/
void welcometogame()
{
int n;
int i,j = 1;
gotoxy(43,18);
color(11);
printf("贪 吃 蛇 游 戏");
color(14); //黄色边框
for (i = 20; i <= 26; i++) //输出上下边框┅
{
for (j = 27; j <= 74; j++) //输出左右边框┇
{
gotoxy(j, i);
if (i == 20 || i == 26)
{
printf("-");
}
else if (j == 27 || j == 74)
{
printf("|");
}
}
}
color(10);
gotoxy(35, 22);
printf("1.开始游戏");
gotoxy(55, 22);
printf("2.游戏说明");
gotoxy(35, 24);
printf("3.退出游戏");
gotoxy(29,27);
color(3);
printf("请选择[1 2 3]:[ ]\b\b"); //\b为退格,使得光标处于[]中间
color(14);
scanf("%d", &n); //输入选项
switch (n)
{
case 1: //选择开始游戏
system("cls");
createMap(); //创建地图
initsnake(); //初始化蛇身
createfood(); //初始化食物
keyboardControl(); //控制键盘按钮
break;
case 2: //选择游戏说明
explation();
break;
case 3: //选择退出游戏
exit(0); //退出游戏
break;
default: //输入非1~3之间的选项
color(12);
gotoxy(40,28);
printf("请输入1~3之间的数!");
getch(); //输入任意键
system("cls"); //清屏
printsnake();
welcometogame();
}
}
/*
创建地图
*/
void createMap()
{
int i,j;
for(i=0;i<58;i+=2) //打印上下边框
{
gotoxy(i,0);
color(6); //深绿色的边框
printf("□");
gotoxy(i,26);
printf("□");
}
for(i=1;i<26;i++) //打印左右边框
{
gotoxy(0,i);
printf("□");
gotoxy(56,i);
printf("□");
}
for(i = 2;i<56;i+=2) //打印中间网格
{
for(j = 1;j<26;j++)
{
gotoxy(i,j);
color(3);
printf("■\n\n");
}
}
}
/*
游戏界面右侧的得分和小提示
*/
void scoreandtips()
{
File_out(); //调用File_out(),读取文件save.txt中的内容
gotoxy(64,4); //确定打印输出的位置
color(11); //设置颜色
printf("☆最高记录☆:%d",HighScore); //打印最高分
gotoxy(64,8);
color(14);
printf("当前得分:%d ",score);
color(15);
gotoxy(73,11);
printf("小 提 示");
gotoxy(60,13);
color(6);
printf("╬ ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ ╬");
gotoxy(60,25);
printf("╬ ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ ╬");
color(3);
gotoxy(64,14);
printf("每个食物得分:%d分",add);
gotoxy(64,16);
printf("不能撞墙,不能咬到自己");
gotoxy(64,18);
printf("用↑ ↓ ← →分别控制蛇的移动");
gotoxy(64,20);
printf("F1键加速,F2键减速");
gotoxy(64,22);
printf("空格键暂停游戏");
gotoxy(64,24);
printf("Esc键退出游戏");
}
/*
初始化蛇身,画蛇身
*/
void initsnake()
{
snake *tail;
int i;
tail=(snake*)malloc(sizeof(snake)); //从蛇尾开始,头插法,以x,y设定开始的位置
tail->x=24; //蛇的初始位置(24,5)
tail->y=5;
tail->next=NULL;
for(i=1;i<=4;i++) //设置蛇身,长度为5
{
head=(snake*)malloc(sizeof(snake)); //初始化蛇头
head->next=tail; //蛇头的下一位为蛇尾
head->x=24+2*i; //设置蛇头位置
head->y=5;
tail=head; //蛇头变成蛇尾,然后重复循环
}
while(tail!=NULL) //从头到尾,输出蛇身
{
gotoxy(tail->x,tail->y);
color(14);
printf("◆"); //输出蛇身,蛇身使用◆组成
tail=tail->next; //蛇头输出完毕,输出蛇头的下一位,一直输出到蛇尾
}
}
/*
随机出现食物
*/
void createfood()
{
snake *food_1;
srand((unsigned)time(NULL)); //初始化随机数
food_1=(snake*)malloc(sizeof(snake)); //初始化food_1
while((food_1->x%2)!=0) //保证其为偶数,使得食物能与蛇头对齐,然后食物会出现在网格线上
{
food_1->x=rand()%52+2; //食物随机出现,食物的x坐标在2~53
}
food_1->y=rand()%24+1; //食物的y坐标在1~24
q=head;
while(q->next==NULL)
{
if(q->x==food_1->x && q->y==food_1->y) //判断蛇身是否与食物重合
{
free(food_1); //如果蛇身和食物重合,那么释放食物指针
createfood(); //重新创建食物
}
q=q->next;
}
gotoxy(food_1->x,food_1->y);
food=food_1;
color(12);
printf("●"); //输出食物
}
/*
判断是否咬到了自己
*/
int biteself()
{
snake *self; //定义self为蛇身上的一个节点
self=head->next; //self是蛇头之外的蛇身上的节点
while(self!=NULL)
{
if(self->x==head->x && self->y==head->y) //如果self和蛇身上的节点重合
{
return 1; //返回1
}
self=self->next;
}
return 0;
}
/*
设置蛇撞墙的情况
*/
void cantcrosswall()
{
if(head->x==0 || head->x==56 ||head->y==0 || head->y==26) //如果蛇头碰到了墙壁
{
endgamestatus=1; //返回第一种情况
endgame(); //出现游戏结束界面
}
}
/*
加速,蛇吃到食物会自动提速,并且按F1会加速
*/
void speedup()
{
if(sleeptime>=50)
{
sleeptime=sleeptime-10;
add=add+2;
}
}
/*
减速,按F2会减速
*/
void speeddown()
{
if(sleeptime<350) //如果时间间隔小于350
{
sleeptime=sleeptime+30; //时间间隔加上30
add=add-2; //每吃一次食物的得分减2
}
}
/*
控制方向
*/
void snakemove() //蛇前进,上U,下D,左L,右R
{
snake * nexthead;
cantcrosswall();
nexthead=(snake*)malloc(sizeof(snake)); //为下一步开辟空间
if(status==U)
{
nexthead->x=head->x; //向上前进时,x坐标不动,y坐标-1
nexthead->y=head->y-1;
nexthead->next=head;
head=nexthead;
q=head; //指针q指向蛇头
if(nexthead->x==food->x && nexthead->y==food->y) //如果下一个有食物 下一个位置的坐标和食物的坐标相同
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆"); //原来食物的位置,从●换成◆
q=q->next; //指针q指向的蛇身的下一位也执行循环里的操作
}
score=score+add; //吃了一个食物,在总分上加上食物的分
speedup();
createfood(); //创建食物
}
else
{
while(q->next->next!=NULL) //如果没遇到食物
{
gotoxy(q->x,q->y);
color(14);
printf("◆"); //蛇正常往前走,输出当前位置的蛇身
q=q->next; //继续输出整个蛇身
}
gotoxy(q->next->x,q->next->y); //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
color(3);
printf("■");
free(q->next); //进行输出■之后,释放指向下一位的指针
q->next=NULL; //指针下一位指向空
}
}
if(status==D)
{
nexthead->x=head->x; //向下前进时,x坐标不动,y坐标+1
nexthead->y=head->y+1;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y) //有食物
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else //没有食物
{
while(q->next->next!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(status==L)
{
nexthead->x=head->x-2; //向左前进时,x坐标向左移动-2,y坐标不动
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)//有食物
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else //没有食物
{
while(q->next->next!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(status==R)
{
nexthead->x=head->x+2; //向右前进时,x坐标向右移动+2,y坐标不动
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)//有食物
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
score=score+add;
speedup();
createfood();
}
else //没有食物
{
while(q->next->next!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("◆");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(biteself()==1) //判断是否会咬到自己
{
endgamestatus=2;
endgame();
}
}
/*
控制键盘按键
*/
void keyboardControl()
{
status=R; //初始蛇向右移动
while(1)
{
scoreandtips();
if(GetAsyncKeyState(VK_UP) && status!=D) //GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态
{
status=U; //如果蛇不是向下前进的时候,按上键,执行向上前进操作
}
else if(GetAsyncKeyState(VK_DOWN) && status!=U) //如果蛇不是向上前进的时候,按下键,执行向下前进操作
{
status=D;
}
else if(GetAsyncKeyState(VK_LEFT)&& status!=R) //如果蛇不是向右前进的时候,按左键,执行向左前进
{
status=L;
}
else if(GetAsyncKeyState(VK_RIGHT)&& status!=L) //如果蛇不是向左前进的时候,按右键,执行向右前进
{
status=R;
}
if(GetAsyncKeyState(VK_SPACE)) //按暂停键,执行pause暂停函数
{
while(1)
{
Sleep(300); //sleep()函数,头文件#include <unistd.h> 令进程暂停,直到达到里面设定的参数的时间
if(GetAsyncKeyState(VK_SPACE)) //按空格键暂停
{
break;
}
}
}
else if(GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus=3; //按esc键,直接到结束界面
break;
}
else if(GetAsyncKeyState(VK_F1)) //按F1键,加速
{
speedup();
}
else if(GetAsyncKeyState(VK_F2)) //按F2键,减速
{
speeddown();
}
Sleep(sleeptime);
snakemove();
}
}
/*
储存最高分进文件
*/
void File_in()
{
FILE *fp;
fp = fopen("save.txt", "w+"); //以读写的方式建立一个名为save.txt的文件
fprintf(fp, "%d", score); //把分数写进文件中
fclose(fp); //关闭文件
}
/*
在文件中读取最高分
*/
void File_out()
{
FILE *fp;
fp = fopen("save.txt", "a+"); //打开文件save.txt
fscanf(fp, "%d", &HighScore); //把文件中的最高分读出来
fclose(fp); //关闭文件
}
/*
游戏说明
*/
void explation()
{
int i,j = 1;
system("cls");
color(15);
gotoxy(44,3);
printf("游戏说明");
color(2);
for (i = 6; i <= 22; i++) //输出上下边框===
{
for (j = 20; j <= 76; j++) //输出左右边框||
{
gotoxy(j, i);
if (i == 6 || i == 22) printf("=");
else if (j == 20 || j == 75) printf("||");
}
}
color(3);
gotoxy(30,8);
printf("tip1: 不能撞墙,不能咬到自己");
color(10);
gotoxy(30,11);
printf("tip2: 用↑.↓.←.→分别控制蛇的移动");
color(14);
gotoxy(30,14);
printf("tip3: F1 为加速,F2 为减速");
color(11);
gotoxy(30,17);
printf("tip4: 按空格键暂停游戏,再按空格键继续");
color(4);
gotoxy(30,20);
printf("tip5: Esc :退出游戏");
getch(); //按任意键返回主界面
system("cls");
printsnake();
welcometogame();
}
/*
结束游戏
*/
void endgame()
{
system("cls");
if(endgamestatus==1)
{
Lostdraw();
gotoxy(35,9);
color(7);
printf("对不起,您撞到墙了。游戏结束!");
}
else if(endgamestatus==2)
{
Lostdraw();
gotoxy(35,9);
color(7);
printf("对不起,您咬到自己了。游戏结束!");
}
else if(endgamestatus==3)
{
Lostdraw();
gotoxy(40,9);
color(7);
printf("您已经结束了游戏。");
}
gotoxy(43,12);
color(14);
printf("您的得分是 %d",score);
if(score >= HighScore)
{
color(10);
gotoxy(33,16);
printf("创纪录啦!最高分被你刷新啦,真棒!!!");
File_in(); //把最高分写进文件
}
else
{
color(10);
gotoxy(33,16);
printf("继续努力吧~ 你离最高分还差:%d",HighScore-score);
}
choose();
}
/*
边框下面的分支选项
*/
void choose()
{
int n;
gotoxy(30,23);
color(12);
printf("重玩一局 [1]");
gotoxy(55,23);
printf("溜了溜了 [2]");
gotoxy(45,25);
color(11);
printf("选择:");
scanf("%d", &n);
switch (n)
{
case 1:
system("cls"); //清屏
score=0; //分数归零
sleeptime=200; //设定初始速度
add = 10; //使add设定为初值,吃一个食物得分10,然后累加
printsnake(); //返回欢迎界面
welcometogame();
break;
case 2:
exit(0); //退出游戏
break;
default:
gotoxy(35,27);
color(12);
printf("※※您的输入有误,请重新输入※※");
system("pause >nul");
endgame();
choose();
break;
}
}
/*
失败界面
*/
void Lostdraw()
{
system("cls");
int i;
gotoxy(45,1);
color(6);
printf(" |-----| "); //匹诺曹的帽子
gotoxy(45,2);
color(6);
printf(" | | ");
gotoxy(43,3);
color(6);
printf("-------------");
gotoxy(44,4);
color(14);
printf("(");
gotoxy(47,4);
color(15);
printf(" > <"); //眼睛
gotoxy(54,4);
color(14);
printf(")");
gotoxy(17,5);
color(11);
printf("+------------------------"); //上边框
gotoxy(35,5);
color(14);
printf("oOOo");
gotoxy(39,5);
color(11);
printf("----------"); //上边框
gotoxy(48,5);
color(14);
printf("| |"); //鼻子
gotoxy(48,6);
color(14);
printf("|_|");
gotoxy(51,5);
color(11);
printf("----------"); //上边框
gotoxy(61,5);
color(14);
printf("oOOo");
gotoxy(65,5);
color(11);
printf("-----------------+"); //上边框
for(i = 6;i<=19;i++) //竖边框
{
gotoxy(17,i);
printf("|");
gotoxy(82,i);
printf("|");
}
gotoxy(17,20);
printf("+------------------------------------------"); //下边框
gotoxy(60,20);
color(11);
printf("----------------------+"); //下边框
}
/*
主函数
*/
int main(int argc, char* argv[])
{
system("mode con cols=110 lines=30"); //设置控制台宽高
printsnake(); //绘制字符蛇
welcometogame(); //欢迎界面
//File_out(); //读取文件信息
//keyboardControl(); //控制键盘按钮
endgame(); //游戏结束
return 0;
}
3、简单到炸的自制迷宫
本程序中的迷宫及其简单,你可以尝试修改地图,增加难度。
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
int main()
{
char a[1000][1000] = {"##########",
"#o # # ",
"# ## ## ##",
"# # ##",
"## ## ##",
"##########" };
int i, x = 1, y = 1;
int count=0;
printf("\n\n\t请不要使用中文输入法!\n\t操作方式:上下左右=WSAD\n\t o 代表你操作的人物, # 代表墙体。\n\t开始你的游戏吧!\n\n\n");
for (i = 0; i < 11; i++)
puts(a[i]);
char ch;
while (x != 1|| y != 9)
{
ch = _getch();
count++;
if (ch == 's')
{
if (a[x + 1][y] != '#')
{
a[x][y] = ' ';
x++;
a[x][y] = 'o';
}
}
if (ch == 'w')
{
if (a[x - 1][y] != '#')
{
a[x][y] = ' ';
x--;
a[x][y] = 'o';
}
}
if (ch == 'a')
{
if (a[x][y - 1] != '#')
{
a[x][y] = ' ';
y--;
a[x][y] = 'o';
}
}
if (ch == 'd')
{
if (a[x][y + 1] != '#')
{
a[x][y] = ' ';
y++;
a[x][y] = 'o';
}
}
system("cls");
if (x == 1 && y == 9)
printf("成功过关\n");
for (i = 0; i < 6; i++)
puts(a[i]);
}
printf("你一共走了%d步\n", count);
Sleep(5000);
return 0;
}
4、不忍直视的双人飞机对战
芜湖,我愿称之为无与伦比。
/*--------------------------------------
project: 双人小游戏
anthor: LLz
操作 移动 逆、顺时针旋转 发射子弹
玩家1 4568 7 9 0
玩家2 adws q e 空格
--------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
// 游戏画面尺寸
#define High 20
#define Width 100
// 全局变量
int position_x,position_y,p_x,p_y,turn_a,turn_b,num_a,num_b,num_max,life_a = 10,life_b = 10; // 飞机位置
int canvas[High][Width] = {0}; // 二维数组存储游戏画布中对应的元素
// 0为空格,1为飞机*,2为子弹|,3为敌机@
int next[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}}; //从右 右下 下 左下
int bullet_a[21][4];
int bullet_b[21][4]; //a b玩家子弹20发;
void gotoxy(int x,int y) //光标移动到(x,y)位置
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
}
void startup() // 数据初始化
{
num_a = 0;
num_b = 0;
turn_a = 0;
turn_b = 0;
p_x = High/2;//左边飞机
p_y = Width* 4 / 5;
canvas[p_x][p_y] = 5;//?
position_x = High/2;//右边飞机
position_y = Width/5;
canvas[position_x][position_y] = 1;
}
void show() // 显示画面
{
gotoxy(0,0); // 光标移动到原点位置,以下重画清屏
int i,j;
for (i=0;i<High;i++)
{
for (j=0;j<Width;j++)
{
if( i == 0 || i == High -1 || j == 0 || j == Width -1){
canvas[i][j] = 4;
printf("0");
continue;
}
if (canvas[i][j]==0)
printf(" "); // 输出空格
else if (canvas[i][j]==1)
printf("A"); // 输出飞机a
else if (canvas[i][j]==2)
printf("B"); // 输出飞机B
else if (canvas[i][j]==3)
printf("o"); // 输出子弹o
else if (canvas[i][j]==4)
printf("+"); // 输出飞机a指向
else if (canvas[i][j]==5)
printf("+"); // 输出飞机b指向
}
printf("\n");
}
//初始血量显示
printf("A:");
for( i = 1; i <= 10; i++ )
if( i <= life_a)
printf("■");
else printf(" ");
printf("\nB: ");
for( i = 1; i <= 10; i++ )
if( i <= life_b)
printf("■");
else printf(" ");
}
void updateWithoutInput() // 与用户输入无关的更新
{
int i,j,k;
num_max = num_a > num_b? num_a : num_b;
for( i = 1; i <= num_max; i++){
if( bullet_a[i][2] == 0 || bullet_a[i][2] == High - 1){
bullet_a[i][0] = -bullet_a[i][0];
}
else if( bullet_a[i][3] == 0 || bullet_a[i][3] == Width - 1){
bullet_a[i][1] = -bullet_a[i][1];
}
if( bullet_b[i][2] == 0 || bullet_b[i][2] == High - 1){
bullet_b[i][0] = -bullet_b[i][0];
}
else if( bullet_b[i][3] == 0 || bullet_b[i][3] == Width - 1){
bullet_b[i][1] = -bullet_b[i][1];
}
canvas[ bullet_a[i][2] ][ bullet_a[i][3] ] = 0;
canvas[ bullet_b[i][2] ][ bullet_b[i][3] ] = 0;
bullet_a[i][2] += bullet_a[i][0];
bullet_a[i][3] += bullet_a[i][1];
bullet_b[i][2] += bullet_b[i][0];
bullet_b[i][3] += bullet_b[i][1];
canvas[ bullet_a[i][2] ][ bullet_a[i][3] ] = 3;
canvas[ bullet_b[i][2] ][ bullet_b[i][3] ] = 3;
}
for (k=1;k<=num_max;k++)
{
if (((position_x==bullet_a[k][2]) && (position_y==bullet_a[k][3]))||((position_x==bullet_b[k][2]) && (position_y==bullet_b[k][3]))) // 敌机撞到我机
{
life_a--;
if( life_a <= 0){
printf("A 玩家失败!\n");
Sleep(3000);
system("pause");
exit(0);
}
}
if (((p_x==bullet_a[k][2]) && (p_y==bullet_a[k][3]))||((p_x==bullet_b[k][2]) && (p_y==bullet_b[k][3]))) // 敌机撞到我机
{
life_b--;
if( life_b <= 0){
printf("B 玩家失败!\n");
Sleep(3000);
system("pause");
exit(0);
}
}
}
}
void updateWithInput() // 与用户输入有关的更新
{
char input;
if(kbhit()) // 判断是否有输入
{
input = getch(); // 根据用户的不同输入来移动,不必输入回车
if (input == 'a' && position_y>1)
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
canvas[position_x][position_y] = 0;
position_y--; // 位置左移
canvas[position_x][position_y] = 1;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == 'd' && position_y<Width-2)
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
canvas[position_x][position_y] = 0;
position_y++; // 位置右移
canvas[position_x][position_y] = 1;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == 'w' && position_x > 1)
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
canvas[position_x][position_y] = 0;
position_x--; // 位置上移
canvas[position_x][position_y] = 1;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == 's'&& position_x < High - 2)
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
canvas[position_x][position_y] = 0;
position_x++; // 位置下移
canvas[position_x][position_y] = 1;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == ' ' && num_a <= 20) // 发射子弹
{
num_a++;
bullet_a[num_a][0] = next[turn_a][0];
bullet_a[num_a][1] = next[turn_a][1];
bullet_a[num_a][2] = position_x + bullet_a[num_a][0];
bullet_a[num_a][3] = position_y + bullet_a[num_a][1];
canvas[ bullet_a[num_a][2] ][ bullet_a[num_a][3] ] = 3;
}
else if (input == 'q') // 炮弹换方向
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
turn_a--;
if(turn_a < 0)
turn_a = 7;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == 'e') // 炮弹换方向
{
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 0;
turn_a++;
if(turn_a > 7)
turn_a = 0;
canvas[position_x + next[turn_a][0]][position_y + next[turn_a][1]] = 4;
}
else if (input == '4' && position_y>1)
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
canvas[p_x][p_y] = 0;
p_y--; // 位置左移
canvas[p_x][p_y] = 2;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
else if (input == '6' && p_y<Width-2)
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
canvas[p_x][p_y] = 0;
p_y++; // 位置右移
canvas[p_x][p_y] = 2;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
else if (input == '8' && p_x > 1)
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
canvas[p_x][p_y] = 0;
p_x--; // 位置上移
canvas[p_x][p_y] = 2;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
else if (input == '5' && p_x < High - 2)
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
canvas[p_x][p_y] = 0;
p_x++; // 位置下移
canvas[p_x][p_y] = 2;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
else if (input == '0' && num_b <= 20) // 发射子弹
{
num_b++;
bullet_b[num_b][0] = next[turn_b][0];
bullet_b[num_b][1] = next[turn_b][1];
bullet_b[num_b][2] = p_x + bullet_b[num_b][0];
bullet_b[num_b][3] = p_y + bullet_b[num_b][1];
canvas[ bullet_b[num_b][2] ][ bullet_b[num_b][3] ] = 3;
}
else if (input == '7') // 炮弹换方向
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
turn_b--;
if(turn_b < 0)
turn_b = 7;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
else if (input == '9') // 炮弹换方向
{
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 0;
turn_b++;
if(turn_b > 7)
turn_b = 0;
canvas[p_x + next[turn_b][0]][p_y + next[turn_b][1]] = 5;
}
}
}
int main()
{
startup(); // 数据初始化
system("color 30");
while (1) // 游戏循环执行
{
show(); // 显示画面
updateWithoutInput(); // 与用户输入无关的更新
updateWithInput(); // 与用户输入有关的更新
}
return 0;
}