注:经大佬建议,该版本较low。只适用于客户端与服务器之间。应改成客户端与客户端之间的。接下来继续研究。争取做到最好!
学习了UDP与TCP协议后,利用这个我们可以简单的实现一些网络小游戏。比如说三子棋。这里不对其做过多的赘述,直接贴上源码。如果有错误,请及时指出。感谢各位老铁!
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
#define ROW 3
#define COL 3
typedef struct Coord{
int x;
int y;
} Coord;
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘
void Printf_Board(char board[ROW][COL], int row, int col);//打印棋盘
void EnterCoord(Coord* c, char board[ROW][COL], int row, int col);//移动
void ServerMove(Coord* c, char board[ROW][COL]);//Server走
void ClientMove(Coord* c, char board[ROW][COL]);//Client走
char CheckWin(char board[ROW][COL], int row, int col);//判断输赢
void Statement();//声明游戏规则
int Win(char board[ROW][COL], int row, int col);//封装一个判断输赢的函数
void menu();//菜单
//game.c
#include "game.h"
void Printf_Board(char board[ROW][COL], int row, int col)//打印棋盘
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf(" %c ",board[i][j]);
if (j < col - 1) {
printf("|");
}
}
printf("\n");
if (i < row - 1) {
printf("---|---|---\n");
}
}
printf("\n");
return;
}
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
board[i][j] = ' ';
}
}
return;
}
void ServerMove(Coord* c, char board[ROW][COL])
{
board[c->x - 1][c->y - 1] = 'X';
}
void ClientMove(Coord* c, char board[ROW][COL])
{
board[c->x - 1][c->y - 1] = 'O';
}
void EnterCoord(Coord* c, char board[ROW][COL], int row, int col)
{
printf("You Run!\n");
while (1) {
printf("enter->");
scanf("%d%d", &c->x, &c->y);
if (board[c->x - 1][c->y - 1] == ' ' && c->x >= 1 &&
c->x <= row && c->y >= 1 && c->y <= col) {
break;
}
else
printf("Coord error!Please enter again!\n");
}
return;
}
int IsFull(char board[ROW][COL], int row, int col)//判断棋盘是否满
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
if (board[i][j] == ' ') {
return 0;
}
}
}
return 1;
}
char CheckWin(char board[ROW][COL], int row, int col)//判断输赢
{
//判断胜利的条件:行、列、两个对角线
//1.行
int i = 0;
for (i = 0; i < row; i++) {
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
return board[i][1];
}
}
//2.列
for (i = 0; i < col; i++) {
if (board[0][i] == board[1][i] && board[1][i] == board[2][i]) {
return board[1][i];
}
}
//3.对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
return board[1][1];
} else if (board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
return board[1][1];
} else if (IsFull(board, ROW, COL) == 1) {
return 'P';
} else {
return ' ';
}
}
void Statement()
{
printf("==============声明============\n");
printf("这里默认让Server先走,走完之后\n");
printf("Client再接着走,Server的落子为\n");
printf("X,Client落子为O!\n");
}
int Win(char board[ROW][COL], int row, int col)
{
char win = CheckWin(board, row, col);//此处可封装
if (win == 'X') {
printf("Server Win!\n");
return 1;
} else if (win == 'O') {
printf("Client Win!\n");
return 2;
} else if (win == 'P') {
printf("平局!\n");
return 3;
}
return 0;
}
void menu(void)
{
printf("*********************************\n");
printf("***** 1.play game 0.exit *****\n");
printf("*********************************\n");
}
//server.c
#include "game.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if(argc != 3) {
printf("usage %s [IP][port]\n",argv[0]);
return 1;
}
int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr(argv[1]);
local.sin_port = htons(atoi(argv[2]));
if(bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0) {
printf("bind error!\n");
return 2;
}
if(listen(listen_sock, 5) < 0) {
printf("listen error!\n");
return 3;
}
struct Coord c;
char board[ROW][COL];
InitBoard(board, ROW, COL);
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
while(1) {
int input = 0;
menu();
printf("Please choose->");
fflush(stdout);
scanf("%d",&input);
if(input == 1) {
printf("Waiting for client...\n");
sleep(2);
int sock = accept(listen_sock, (struct sockaddr*)&client_addr, &len);
if(sock > 0) {
printf("Client comming!\n");
}
Statement();
Printf_Board(board, ROW, COL);
while(1) {
EnterCoord(&c, board, ROW, COL);
ServerMove(&c, board);
Printf_Board(board, ROW, COL);
write(sock, &c, sizeof(c));
int ret = Win(board, ROW, COL);
if(ret != 0) {
break;
}
printf("Waiting Client Run!\n");
read(sock, &c, sizeof(c));
ClientMove(&c, board);
Printf_Board(board, ROW, COL);
ret = Win(board, ROW, COL);
if(ret != 0) {
break;
}
}
close(sock);
} else if(input == 0) {
printf("exit!\n");
break;
} else {
printf("Enter error! Please choose again!\n");
continue;
}
}
close(listen_sock);
return 0;
}
//client.c
#include "game.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if(argc != 3) {
printf("usage %s [IP][port]\n",argv[0]);
return 1;
}
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0) {
printf("socket error!\n");
return 2;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
struct Coord c;
char board[ROW][COL];
InitBoard(board, ROW, COL);
while(1) {
menu();
int input = 0;
printf("Please choose->");
fflush(stdout);
scanf("%d",&input);
if(input == 1) {
if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
printf("connect error!\n");
return 3;
}
Statement();
Printf_Board(board, ROW, COL);
while(1) {
printf("Waiting Server Run!\n");
read(sock, &c, sizeof(c));
ServerMove(&c, board);
Printf_Board(board, ROW, COL);
int ret = Win(board, ROW, COL);
if(ret != 0) {
break;
}
EnterCoord(&c, board, ROW, COL);
ClientMove(&c, board);
write(sock, &c, sizeof(c));
Printf_Board(board, ROW, COL);
ret = Win(board, ROW, COL);
if(ret != 0) {
break;
}
}
} else if(input == 0) {
printf("exit!\n");
break;
} else {
printf("Enter error! Please choose again!\n");
continue;
}
}
close(sock);
return 0;
}
下面附上游戏截图:
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!