socket联网写一个联网五子棋
时间: 2023-07-25 14:24:25 浏览: 34
好的,下面是一个简单的 C 语言 Socket 联网五子棋游戏的示例代码:
服务器端:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define PORT 8888
#define MAX_CLIENTS 2
#define BOARD_SIZE 15
int board[BOARD_SIZE][BOARD_SIZE]; // 棋盘
int current_player = 1; // 当前玩家
int client_fds[MAX_CLIENTS]; // 客户端 Socket 文件描述符
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
void init_board() {
memset(board, 0, sizeof(board));
}
void print_board() {
printf(" ");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%c ", 'A' + i);
}
printf("\n");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%2d", i + 1);
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 0) {
printf(" .");
} else if (board[i][j] == 1) {
printf(" X");
} else {
printf(" O");
}
}
printf("\n");
}
}
int check_win(int x, int y) {
int count = 1;
int i, j;
// 检查横向
i = x;
j = y - 1;
while (j >= 0 && board[i][j] == board[x][y]) {
count++;
j--;
}
j = y + 1;
while (j < BOARD_SIZE && board[i][j] == board[x][y]) {
count++;
j++;
}
if (count >= 5) {
return 1;
}
// 检查纵向
count = 1;
i = x - 1;
j = y;
while (i >= 0 && board[i][j] == board[x][y]) {
count++;
i--;
}
i = x + 1;
while (i < BOARD_SIZE && board[i][j] == board[x][y]) {
count++;
i++;
}
if (count >= 5) {
return 1;
}
// 检查左上到右下
count = 1;
i = x - 1;
j = y - 1;
while (i >= 0 && j >= 0 && board[i][j] == board[x][y]) {
count++;
i--;
j--;
}
i = x + 1;
j = y + 1;
while (i < BOARD_SIZE && j < BOARD_SIZE && board[i][j] == board[x][y]) {
count++;
i++;
j++;
}
if (count >= 5) {
return 1;
}
// 检查左下到右上
count = 1;
i = x + 1;
j = y - 1;
while (i < BOARD_SIZE && j >= 0 && board[i][j] == board[x][y]) {
count++;
i++;
j--;
}
i = x - 1;
j = y + 1;
while (i >= 0 && j < BOARD_SIZE && board[i][j] == board[x][y]) {
count++;
i--;
j++;
}
if (count >= 5) {
return 1;
}
return 0;
}
void send_message(int player, const char* message) {
write(client_fds[player], message, strlen(message));
}
void* thread_func(void* arg) {
int player = *(int*)arg;
// 发送欢迎信息
char message[1024];
memset(message, 0, sizeof(message));
sprintf(message, "Welcome! You are player %d.\n", player + 1);
send_message(player, message);
// 游戏开始
while (1) {
// 等待对方下棋
pthread_mutex_lock(&mutex);
if (current_player != player) {
pthread_mutex_unlock(&mutex);
usleep(100000);
continue;
}
// 提示当前玩家下棋
memset(message, 0, sizeof(message));
sprintf(message, "Your turn, player %d.\n", player + 1);
send_message(player, message);
// 接收玩家下棋位置
memset(message, 0, sizeof(message));
read(client_fds[player], message, sizeof(message));
int x = message[0] - '1';
int y = message[1] - 'A';
// 下棋,并检查胜负
if (board[x][y] == 0) {
board[x][y] = player + 1;
print_board();
if (check_win(x, y)) {
memset(message, 0, sizeof(message));
sprintf(message, "You win!\n");
send_message(player, message);
memset(message, 0, sizeof(message));
sprintf(message, "Player %d wins!\n", player + 1);
send_message((player + 1) % 2, message);
break;
}
current_player = (player + 1) % 2;
} else {
memset(message, 0, sizeof(message));
sprintf(message, "Invalid move. Please try again.\n");
send_message(player, message);
}
pthread_mutex_unlock(&mutex);
}
// 关闭 Socket
close(client_fds[player]);
return NULL;
}
int main() {
int server_fd;
struct sockaddr_in server_addr;
int client_fd;
struct sockaddr_in client_addr;
pthread_t threads[MAX_CLIENTS];
int i, j;
// 创建 Socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
// 绑定端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
// 监听连接
listen(server_fd, MAX_CLIENTS);
// 初始化棋盘
init_board();
// 接受客户端连接
for (i = 0; i < MAX_CLIENTS; i++) {
int len = sizeof(client_addr);
client_fds[i] = accept(server_fd, (struct sockaddr*)&client_addr, &len);
printf("New client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
// 启动线程
for (i = 0; i < MAX_CLIENTS; i++) {
pthread_create(&threads[i], NULL, thread_func, &i);
}
// 等待线程结束
for (i = 0; i < MAX_CLIENTS; i++) {
pthread_join(threads[i], NULL);
}
// 关闭 Socket
close(server_fd);
return 0;
}
```
该示例代码创建了一个 Socket 服务器,绑定在本地 8888 端口上,等待客户端连接。每当有两个客户端连接成功后,服务器就会启动两个线程,分别处理两个客户端的请求。每个线程维护一个棋手的状态,接收玩家下棋位置,更新棋盘,检查胜负等操作,并将对应的消息发送给客户端。