用java的AIO实现“剪刀石头布”的网络游戏的代码
时间: 2024-02-13 13:06:07 浏览: 130
以下是用Java AIO实现“剪刀石头布”网络游戏的代码示例:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
public class GameServer {
private static final int PORT = 8888;
private static final int BUFFER_SIZE = 1024;
private static final String[] GESTURES = {"剪刀", "石头", "布"};
private static final String[] RESULTS = {"平局", "胜利", "失败"};
private static class Player {
public AsynchronousSocketChannel channel;
public ByteBuffer buffer;
public int gesture = -1;
}
private static List<Player> players = new ArrayList<>();
public static void main(String[] args) throws Exception {
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(10));
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress(PORT));
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel channel, Void attachment) {
server.accept(null, this);
Player player = new Player();
player.channel = channel;
player.buffer = ByteBuffer.allocate(BUFFER_SIZE);
players.add(player);
channel.read(player.buffer, player, new CompletionHandler<Integer, Player>() {
@Override
public void completed(Integer result, Player player) {
if (result == -1) {
removePlayer(player);
} else {
player.buffer.flip();
String message = new String(player.buffer.array(), 0, player.buffer.limit()).trim();
player.buffer.clear();
if (message.equals("剪刀") || message.equals("石头") || message.equals("布")) {
player.gesture = findGestureIndex(message);
if (isAllGestured()) {
String resultMessage = getResultMessage();
broadcast(resultMessage);
resetGestures();
}
}
channel.read(player.buffer, player, this);
}
}
@Override
public void failed(Throwable exc, Player player) {
removePlayer(player);
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
}
});
Thread.currentThread().join();
}
private static void removePlayer(Player player) {
players.remove(player);
try {
player.channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static int findGestureIndex(String gesture) {
for (int i = 0; i < GESTURES.length; i++) {
if (GESTURES[i].equals(gesture)) {
return i;
}
}
return -1;
}
private static boolean isAllGestured() {
for (Player player : players) {
if (player.gesture == -1) {
return false;
}
}
return true;
}
private static String getResultMessage() {
int[] gestures = new int[players.size()];
for (int i = 0; i < players.size(); i++) {
gestures[i] = players.get(i).gesture;
}
int total = gestures.length;
int[] counts = new int[GESTURES.length];
for (int i = 0; i < total; i++) {
counts[gestures[i]]++;
}
StringBuilder resultBuilder = new StringBuilder();
for (int i = 0; i < total; i++) {
int gesture1 = gestures[i];
int winCount = 0;
int drawCount = 0;
for (int j = 0; j < total; j++) {
if (i != j) {
int gesture2 = gestures[j];
int result = (gesture1 - gesture2 + GESTURES.length) % GESTURES.length;
if (result == 0) {
drawCount++;
} else if (result == 1 || result == 2) {
winCount++;
}
}
}
resultBuilder.append("玩家").append(i + 1).append("出了").append(GESTURES[gesture1]);
if (drawCount == total - 1) {
resultBuilder.append(", 结果是平局");
} else if (winCount == total - 1) {
resultBuilder.append(", 结果是胜利");
} else {
resultBuilder.append(", 结果是失败");
}
resultBuilder.append("\n");
}
return resultBuilder.toString();
}
private static void resetGestures() {
for (Player player : players) {
player.gesture = -1;
}
}
private static void broadcast(String message) {
for (Player player : players) {
try {
player.channel.write(ByteBuffer.wrap(message.getBytes())).get();
} catch (Exception e) {
removePlayer(player);
}
}
}
}
```
在这个示例中,我们使用`AsynchronousServerSocketChannel`来监听客户端连接,并使用`CompletionHandler`来处理连接、读取和写入操作。我们创建了一个`Player`类来表示每个玩家,并用一个`List`来保存所有玩家的信息。每当有一个新玩家连接时,我们会将其加入到`players`列表中,并开始异步读取其输入。如果读取到的输入是有效的手势(即“剪刀”、“石头”或“布”),则将其存储到相应的`Player`对象中,并检查是否已经收到了所有玩家的手势。如果是,则计算结果并将其广播给所有玩家。在处理读取和写入操作时,我们都需要检查是否有任何异常发生,并在发生异常时删除相应的`Player`对象。
阅读全文