我有一个非常简单的二十一点应用程序,但是我必须使其成为客户端服务器,我也不知道如何。我将非常感谢您的帮助。
所以,这是主类游戏:
package game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game extends JFrame implements ActionListener {
private Deck deck;
public Player player = new Player("player");
public Player dealer = new Player("dealer");
int dealerCount = 0;
int playerCount = 0;
private JButton jbtnHit = new JButton("Hit");
private JButton jbtnStay = new JButton("Stay");
private JButton jbtnDeal = new JButton("Deal");
private JLabel jlblStatus = new JLabel(" ", JLabel.CENTER);
private JLabel jlblDealerCount = new JLabel(" ", JLabel.CENTER);
private JLabel jlblPlayerCount = new JLabel(" ", JLabel.CENTER);
JPanel playerPanel = new JPanel();
JPanel dealerPanel = new JPanel();
JPanel buttonsPanel = new JPanel();
JPanel statusPanel = new JPanel();
JPanel countPanel = new JPanel();
Game() {
JFrame gameFrame = new JFrame("BlackJack");
gameFrame.setIconImage(Toolkit.getDefaultToolkit().getImage("cards/10.png"));
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonsPanel.add(jbtnHit);
buttonsPanel.add(jbtnStay);
buttonsPanel.add(jbtnDeal);
statusPanel.add(jlblStatus);
countPanel.add(jlblDealerCount);
countPanel.add(jlblPlayerCount);
jbtnHit.addActionListener(this);
jbtnStay.addActionListener(this);
jbtnDeal.addActionListener(this);
jbtnHit.setEnabled(false);
jbtnStay.setEnabled(false);
dealerPanel.setBackground(Color.GREEN);
playerPanel.setBackground(Color.GREEN);
buttonsPanel.setBackground(Color.GREEN);
statusPanel.setBackground(Color.GREEN);
countPanel.setBackground(Color.GREEN);
gameFrame.setLayout(new BorderLayout());
gameFrame.add(dealerPanel, BorderLayout.NORTH);
gameFrame.add(playerPanel, BorderLayout.CENTER);
gameFrame.add(buttonsPanel, BorderLayout.SOUTH);
gameFrame.add(statusPanel, BorderLayout.WEST);
gameFrame.add(countPanel, BorderLayout.EAST);
gameFrame.repaint();
gameFrame.setSize(500, 350);
gameFrame.setVisible(true);
}
private void hitPlayer() {
Card newCard = player.dealTo(deck.dealFrom());
playerPanel.add(new JLabel(new ImageIcon("cards/" + newCard.toString())));
playerPanel.updateUI();
}
private void hitDealerDown() {
Card newCard = dealer.dealTo(deck.dealFrom());
dealerPanel.add(new JLabel(new ImageIcon("cards/b2fv.png")));
dealerPanel.updateUI();
}
private void hitDealer() {
Card newCard = dealer.dealTo(deck.dealFrom());
dealerPanel.add(new JLabel(new ImageIcon("cards/" + newCard.toString())));
dealerPanel.updateUI();
}
private void deal() {
playerPanel.removeAll();
dealerPanel.removeAll();
playerPanel.updateUI();
dealerPanel.updateUI();
player.reset();
dealer.reset();
if (deck == null || deck.size() < 15) {
deck = new Deck();
deck.shuffle();
jlblStatus.setText("Shuffling");
}
hitPlayer();
hitDealerDown();
hitPlayer();
hitDealer();
}
private void checkWinner() {
dealerPanel.removeAll();
for (int i = 0; i < dealer.inHand(); i++) {
dealerPanel.add(new JLabel(new ImageIcon("cards/" + dealer.cards[i].toString())));
}
if (player.value() > 21) {
jlblStatus.setText("Player Busts");
dealerCount++;
} else if (dealer.value() > 21) {
jlblStatus.setText("Dealer Busts");
playerCount++;
} else if (dealer.value() == player.value()) {
jlblStatus.setText("Push");
} else if (dealer.value() < player.value()) {
jlblStatus.setText("Player Wins");
playerCount++;
} else {
jlblStatus.setText("Dealer Wins");
dealerCount++;
}
jlblDealerCount.setText(dealerCount+" :");
jlblPlayerCount.setText(""+playerCount);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jbtnHit) {
hitPlayer();
if (player.value() > 21) {
checkWinner();
jbtnHit.setEnabled(false);
jbtnStay.setEnabled(false);
jbtnDeal.setEnabled(true);
}
}
if (e.getSource() == jbtnStay) {
while (dealer.value() < 17 || player.value() > dealer.value()) {
hitDealer();
}
checkWinner();
jbtnHit.setEnabled(false);
jbtnStay.setEnabled(false);
jbtnDeal.setEnabled(true);
}
if (e.getSource() == jbtnDeal) {
deal();
jlblStatus.setText(" ");
jbtnHit.setEnabled(true);
jbtnStay.setEnabled(true);
jbtnDeal.setEnabled(false);
}
}
public static void main(String[] args) {
new Game();
}
}
这是课程卡:
package game;
class Card {
private int cardNumber;
private int rank;
private String front;
Card(int cardNumber, int rank, String front) {
this.cardNumber = cardNumber;
this.rank = rank;
this.front = front;
}
public boolean isAce() {
return rank == 0;
}
public int rank() {
if (rank == 0) {
return 1;
}
if (rank >= 9) {
return 10;
}
return rank + 1;
}
public String toString() {
return this.front;
}
}
这是Deck类:
package game;
public class Deck {
final static int DECK_SIZE = 52;
private Card[] cards;
private int N = 0;
public Deck() {
cards = new Card[DECK_SIZE];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 13; j++) {
cards[N] = new Card(N, j, i + "" + j + ".png");
N++;
}
}
}
public Card dealFrom() {
return cards[--N];
}
public boolean isEmpty() {
return (N == 0);
}
public int size() {
return N;
}
public void shuffle() {
for (int i = 0; i < N; i++) {
int r = (int) (Math.random() * i);
Card swap = cards[i];
cards[i] = cards[r];
cards[r] = swap;
}
}
}
这是类播放器:
package game;
public class Player {
final static int MAX_CARDS = 52;
public Card[] cards = new Card[MAX_CARDS];
private int N = 0;
private String name;
public Player(String name) {
this.name = name;
}
public int inHand() {
return N;
}
public Card dealTo(Card c) {
cards[N++] = c;
return c;
}
public void reset() {
N = 0;
}
public int value() {
int val = 0;
boolean hasAce = false;
for (int i = 0; i < N; i++) {
val = val + cards[i].rank();
if (cards[i].isAce()) {
hasAce = true;
}
}
if (hasAce && (val <= 11)) {
val = val + 10;
}
return val;
}
}
我需要有关如何做此游戏客户端服务器和多线程游戏的任何信息和示例。
这应该是使用套接字的网络应用程序。
最佳答案
在编写网络应用程序时,必须首先确定游戏用户之间共享哪些数据。对于二十一点而言,要共享的数据(又称“游戏状态”)非常简单:
轮到的玩家
仍在副牌中的卡片
每个玩家桌上的纸牌
每个玩家有多少钱
一旦计划好所有这些,就可以创建对象来表示游戏状态。例如:
public class GameState {
public enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES }
public enum Rank { ONE, TWO, THREE, FOUR, FIVE, SIX ... ACE }
public static class Card {
Suit suit;
Rank rank;
}
public static class Deck {
List<Card> cards; // Cards remaining in the deck
}
public static class Player {
// Cards on the table for a player
List<Card> cards;
Integer id;
Double money;
}
HashMap<Integer, Player> players;
Integer activePlayerId;
}
接下来,我们需要一种机制来在所有玩家之间同步此状态。对于像二十一点这样的游戏,这样做的一种方法是在每个玩家回合之后同步整个状态。也就是说,在每个回合结束时,将整个游戏状态通过网络发送给所有玩家。要发送游戏状态,最简单的方法是使用中央服务器进程来保留最新状态的副本。中央服务器定期将游戏状态发送给玩家,以使其保持同步。
现在,我们需要客户端可以用来与服务器通信的协议。在游戏开始时,客户端进行连接,然后等待服务器启动游戏。在那之后,客户端和服务器以同步的方式进行通信,就好像他们正在对话一样。这是一个例子:
Client 1: Connect
Server: OK
Client 2: Connect
Server: OK
Server: Start game
Server: Sync <send the initial game state>
Server: Place bids
Client 1: Bid 50
Client 2: Bid 100
Server: Client 1's turn
Client 1: Stay
Server: Sync <send new game state>
Server: Client 2's turn
Client 2: Hit
Server: Sync <send new game state>
...
直到游戏结束。要在客户端和服务器之间发送数据和协议对话,可以使用套接字。我不会在这里讨论,因为在Interwebs上有很多关于使用套接字的教程,like this one.
祝好运并玩得开心点!