这篇文章主要介绍“Android如何实现五子棋游戏局域网版”,在日常操作中,相信很多人在Android如何实现五子棋游戏局域网版问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android如何实现五子棋游戏局域网版”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
实现环境: android studio 3.2.1, 手机分辨率为: 1920 * 1080
局域网采用 Socket 连接
分主活动类,主机类,客户端类
代码如下
清单文件要添加的权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
主活动:
package fivechess;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
public class MainActivity extends AppCompatActivity {
private TextView txtMain;
private Button serverBtn;
private TextView txtClient;
private EditText ipText;
private Button clientBtn;
private int ip = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
txtMain = (TextView) findViewById(R.id.txtMain);
serverBtn = (Button) findViewById(R.id.serverBtn);
txtClient = (TextView) findViewById(R.id.txtClient);
ipText = (EditText) findViewById(R.id.ipText);
clientBtn = (Button) findViewById(R.id.clientBtn);
ipText.setText(getPreference("myIp"));
// 显示本机的 ip 地址
setIp();
// 根据按钮来判断作为主机还是客户端
final ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
serverBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ServerView serverView = new ServerView(MainActivity.this, ip, MainActivity.this);
addContentView(serverView, params);
serverView.startConn();
// 将当前控件隐藏掉
viewGone();
}
});
clientBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ipText.getText().toString().isEmpty()) {
Toast.makeText(MainActivity.this, "IP 不能为空!", Toast.LENGTH_SHORT).show();
return;
}
ClientView clientView = new ClientView(MainActivity.this, ipText.getText().toString(), ip, MainActivity.this);
addContentView(clientView, params);
clientView.startJoin();
// 将当前控件隐藏掉
viewGone();
}
});
}
// 存储当前输入的 ip
public void setMyIp() {
setPreference("myIp", ipText.getText().toString());
}
// 用于获取本机 ip 地址
public void setIp() {
String s;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface face = en.nextElement();
for (Enumeration<InetAddress> enAddr = face.getInetAddresses(); enAddr.hasMoreElements();) {
InetAddress addr = enAddr.nextElement();
if (!addr.isLoopbackAddress()) {
s = addr.getHostAddress();
// 只获取局域网地址
if ("192".equals(s.substring(0, 3))) {
txtMain.setText(txtMain.getText().toString() + " 主机ip: " + s);
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
}
// 隐藏主活动的辅助空间
public void viewGone() {
txtMain.setVisibility(View.GONE);
serverBtn.setVisibility(View.GONE);
txtClient.setVisibility(View.GONE);
ipText.setVisibility(View.GONE);
clientBtn.setVisibility(View.GONE);
}
// 用于获取上次的ip输入地址
public String getPreference(String key) {
return PreferenceManager.getDefaultSharedPreferences(this).getString(key, "192.168.");
}
// 用于存储数据到本地
public void setPreference(String key, String value) {
PreferenceManager.getDefaultSharedPreferences(this).edit().putString(key, value).apply();
}
}
布局:
效果图
代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/txtMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="作为主机"
android:textColor="#000" />
<Button
android:id="@+id/serverBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="start server" />
<TextView
android:id="@+id/txtClient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="作为客户端"
android:textColor="#000" />
<EditText
android:id="@+id/ipText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ip"
android:text="192.168.31.163" />
<Button
android:id="@+id/clientBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="client connection" />
</LinearLayout>
主机类:
package fivechess;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class ServerView extends View {
// 上边距
public static final int TOP = 200;
// 棋盘的左,上边距
public static final int MARGINLEFT = 50, MARGINTOP = 100 + TOP;
// 棋子的宽度,视情况而定
public static final int CHESSW = 62;
// 格子的宽度,视情况而定
public static final int W = 70;
// 14个格子,15条行列坐标
public static final int L = 15;
public static final int BLOCKL = 14;
// 棋的颜色标记
public static final int BLACK = 2, WHITE = 1;
// public static final int NULL = -1;
// 棋盘的宽度
private int width = W * BLOCKL;
// 棋盘的高度
private int height = W * BLOCKL;
// 标记我方的棋的颜色
private int player;
// 存储所有走过的棋的信息,主要为坐标
private List<String> allList = new ArrayList<>();
// 存储我方走过的棋的信息
private List<String> myList = new ArrayList<>();
// 存储对方走过的棋的信息
private List<String> enemyList = new ArrayList<>();
// 是否可以走棋
private boolean canPlay;
// 是否有滑动事件
private boolean isMove;
// 用于开启服务器,所有的网络请求都要在线程中执行
private ServerSocket serverSocket;
// 用于与客户端交互
private Socket socket;
// 对方端口
private int port;
// 用于发送消息
private PrintWriter pw;
// 主活动
private MainActivity mainActivity;
// 提示文本框
private TextView tvTip;
// 重新开始
private Button btnRestart;
public ServerView(Context context, int port, MainActivity mainActivity) {
super(context);
this.port = port;
this.mainActivity = mainActivity;
// 初始化棋盘
initMap();
// 添加提示文本框控件和重新开始按钮
ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tvTip = new TextView(context);
tvTip.setText("等待连接...");
tvTip.setX(500);
tvTip.setY(20);
mainActivity.addContentView(tvTip, params);
btnRestart = new Button(context);
btnRestart.setText("重新开始");
btnRestart.setX(MARGINLEFT);
btnRestart.setY(20);
mainActivity.addContentView(btnRestart, params);
btnRestart.setEnabled(false);
btnRestart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 重新开始游戏
restartGame();
// 发送消息给客户端
sendMes("restart");
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isMove = false;
break;
// 判断是否为滑动事件
case MotionEvent.ACTION_MOVE:
isMove = true;
break;
case MotionEvent.ACTION_UP:
if (!canPlay) {
break;
}
// 只可处理点击事件
if (!isMove) {
// 获取当前点击位置的 x, y 坐标
int x = (int) event.getX() - MARGINLEFT;
int y = (int) event.getY() - MARGINTOP;
// 是否在棋盘外
if (x < -W / 2 || x > width + W / 2 || y < -W / 2 || y > width + W / 2) {
break;
}
// 转化为棋盘的 col 列坐标
// x % W > W / 2 ? 1 : 0 为当前的位置的求模后是否满足大于一半的宽度,
// 若大于则把它安排到下一个位置,否则不变
x = x / W + (x % W > W / 2 ? 1 : 0);
// 转化为棋盘的 row 行坐标
y = y / W + (y % W > W / 2 ? 1 : 0);
// 设置移动信息
String move = y + "|" + x;
// 当前位置是否有棋存在
if (allList.contains(move)) {
break;
}
// 把当前移动位置添加到所有列表中
allList.add(move);
// 把当前移动位置添加到我方列表中
myList.add(move);
// 将移动消息发送给对面
sendMes("move|" + move);
// 轮到对方下
canPlay = false;
// 设置提示信息
tvTip.setText("对方下");
// 更新视图
invalidate();
// 判断是否赢了
if (isWin()) {
Toast.makeText(getContext(), "黑棋获胜!", Toast.LENGTH_SHORT).show();
tvTip.setText("我方获胜!");
}
}
}
return true;
}
});
}
// 开启服务器
public void startConn() {
// 只能在线程(异步)中执行
new Timer().schedule(new TimerTask() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
// 获取客户端信息,若无客户端连接则会一直暂停在这
socket = serverSocket.accept();
setTip("连接成功!");
// 发送已连接给客户端
sendMes("conn|");
// 开启接受消息的线程
new MyThread().start();
// 更新视图
invalidate();
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0);
}
// 是否赢了
private boolean isWin() {
// 好像有点多此一举...
return isCanLink();
}
// 是否有了输赢
private boolean isCanLink() {
// 黑棋先,服务端为黑棋,客户端为白棋
// 判断最后下的是谁,为0为白棋,为1为黑棋
int who = allList.size() % 2;
// 将行列坐标分割出来
String[] t = allList.get(allList.size() - 1).split("\\|");
// 行坐标
int r1 = Integer.valueOf(t[0]);
// 列坐标
int c1 = Integer.valueOf(t[1]);
// 垂直方向是否有五子
if (canVLink(who, r1, c1)) {
return true;
}
// 水平方向是否有五子
if (canHLink(who, r1, c1)) {
return true;
}
// 左下右上方向
if (canLeftObliqueLink(who, r1, c1)) {
return true;
}
// 左上右下方向
if (canRightObliqueLink(who, r1, c1)) {
return true;
}
return false;
}
// 左上右下方向
private boolean canRightObliqueLink(int who, int r1, int c1) {
// 记录连子的个数
int count = 0;
// 遍历要用到的行列坐标
int r2;
int c2;
// 黑棋
if (who == 1) {
// left top
r2 = r1 - 1;
c2 = c1 - 1;
// 往左上方向遍历,若存在则表示有连棋
while (myList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2--;
}
// right down
r2 = r1 + 1;
c2 = c1 + 1;
// 往右下方向遍历
while (myList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2++;
}
// 若有四个以上则代表构成五子
if (count >= 4) {
return true;
}
} else {
// 红棋
// right top
r2 = r1 - 1;
c2 = c1 - 1;
// 往左上方向遍历
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2--;
}
// left down
r2 = r1 + 1;
c2 = c1 + 1;
// 往右下方向遍历
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2++;
}
// 若有四个以上则代表构成五子
if (count >= 4) {
return true;
}
}
return false;
}
// 左下右上方向
private boolean canLeftObliqueLink(int who, int r1, int c1) {
int count = 0;
int r2;
int c2;
// 黑棋
if (who == 1) {
// right top
r2 = r1 - 1;
c2 = c1 + 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2++;
}
// left down
r2 = r1 + 1;
c2 = c1 - 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2--;
}
if (count >= 4) {
return true;
}
} else {
// 白棋
// right top
r2 = r1 - 1;
c2 = c1 + 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2++;
}
// left down
r2 = r1 + 1;
c2 = c1 - 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2--;
}
if (count >= 4) {
return true;
}
}
return false;
}
// 水平方向
private boolean canHLink(int who, int r1, int c1) {
int count = 0;
int c2;
// 黑棋
if (who == 1) {
// left
c2 = c1 - 1;
while (myList.contains(r1 + "|" + c2)) {
count++;
c2--;
}
// right
c2 = c1 + 1;
while (myList.contains(r1 + "|" + c2)) {
count++;
c2++;
}
if (count >= 4) {
return true;
}
} else {
// 白棋
// left
c2 = c1 - 1;
while (enemyList.contains(r1 + "|" + c2)) {
count++;
c2--;
}
// right
c2 = c1 + 1;
while (enemyList.contains(r1 + "|" + c2)) {
count++;
c2++;
}
if (count >= 4) {
return true;
}
}
return false;
}
// 垂直方向
private boolean canVLink(int who, int r1, int c1) {
int count = 0;
int r2;
// 黑棋
if (who == 1) {
// top
r2 = r1 - 1;
while (myList.contains(r2 + "|" + c1)) {
count++;
r2--;
}
// down
r2 = r1 + 1;
while (myList.contains(r2 + "|" + c1)) {
count++;
r2++;
}
if (count >= 4) {
return true;
}
} else {
// 白棋
// top
r2 = r1 - 1;
while (enemyList.contains(r2 + "|" + c1)) {
count++;
r2--;
}
// down
r2 = r1 + 1;
while (enemyList.contains(r2 + "|" + c1)) {
count++;
r2++;
}
if (count >= 4) {
return true;
}
}
return false;
}
// 接受消息的线程
class MyThread extends Thread {
@Override
public void run() {
BufferedReader br = null;
InputStreamReader isr = null;
try {
String t;
while (true) {
// 睡眠一段时间,不必每毫秒都执行
sleep(100);
isr = new InputStreamReader(socket.getInputStream());
br = new BufferedReader(isr);
// 是否接受到了消息
if (br.ready()) {
String cmd = br.readLine();
// 分割信息
String[] array = cmd.split("\\|");
switch (array[0]) {
// 一定是服务器接受到这个消息
case "join":
// 服务器一定为黑棋
player = BLACK;
// 我方先下
canPlay = true;
// 发送消息给客户端
sendMes("conn|");
setTip("我下");
// UI 更新一定在主线程中执行
// 重新开始按钮可以点了,这个方法可以赚到主线程中
post(new Runnable() {
@Override
public void run() {
btnRestart.setEnabled(true);
}
});
//
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mainActivity, "你是黑棋", Toast.LENGTH_SHORT).show();
}
});
break;
case "move":
// 存储对方走的棋坐标
t = array[1] + "|" + array[2];
allList.add(t);
enemyList.add(t);
// 我方走棋
canPlay = true;
setTip("我下");
// 是否有了输赢
if (isWin()) {
post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "白棋获胜!", Toast.LENGTH_SHORT).show();
tvTip.setText("对方获胜!");
canPlay = false;
}
});
}
invalidate();
break;
case "restart":
// 重新开始游戏
restartGame();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void setTip(final String s) {
post(new Runnable() {
@Override
public void run() {
tvTip.setText(s);
}
});
}
// 发送消息个客户端
private void sendMes(final String s) {
new Thread(new Runnable() {
@Override
public void run() {
try {
pw = new PrintWriter(socket.getOutputStream());
pw.println(s);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 初始化棋盘,把列表全部清空
private void initMap() {
allList.clear();
myList.clear();
enemyList.clear();
}
// 调用 invalidate 是执行
@Override
protected void onDraw(Canvas canvas) {
// 画笔,设置线条的样式
Paint paint = new Paint();
paint.setColor(Color.parseColor("#FFE869"));
// 设置棋盘的位置,视情况而定
canvas.drawRect(0, TOP, 1080, 1400 + TOP, paint);
// 设置画笔颜色为黑色,用于画棋盘坐标系
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
for (int i = 0; i < L; i++) {
int hx = MARGINLEFT;
int hy = MARGINTOP + i * W;
int vx = MARGINLEFT + i * W;
int vy = MARGINTOP;
// 画竖线
canvas.drawLine(hx, hy, MARGINLEFT + width, hy, paint);
// 画横线
canvas.drawLine(vx, vy, vx, MARGINTOP + height, paint);
}
// 画初始的九个星位
RectF rectF = new RectF();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int w = 20;
int x = MARGINLEFT + W * 3 + j * W * 4 - w / 2;
int y = MARGINTOP + W * 3 + i * W * 4 - w / 2;
rectF.set(x, y, x + 20, y + 20);
// 画椭圆
canvas.drawOval(rectF, paint);
}
}
// 画棋子
String[] t;
int r, c;
for (int i = 0; i < allList.size(); i++) {
// 黑棋先,所以黑棋索引为双数,白棋为单数
if (i % 2 == 0) {
paint.setColor(Color.BLACK);
} else {
paint.setColor(Color.WHITE);
}
t = allList.get(i).split("\\|");
// 行坐标
r = Integer.valueOf(t[0]);
// 列坐标
c = Integer.valueOf(t[1]);
// 使棋子的中心点对其坐标顶点
c = MARGINLEFT + c * W - CHESSW / 2;
r = MARGINTOP + r * W - CHESSW / 2;
rectF.set(c, r, c + CHESSW, r + CHESSW);
// 画椭圆
canvas.drawOval(rectF, paint);
}
}
// 重新开始游戏
public void restartGame() {
allList.clear();
myList.clear();
enemyList.clear();
canPlay = true;
setTip("我下");
post(new Runnable() {
@Override
public void run() {
invalidate();
}
});
}
}
客户端类: 与主机有区别的地方就是 建立连接和接受消息的线程,其它的地方大体相同
代码如下:
package fivechess;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class ClientView extends View {
public static final int TOP = 200;
public static final int MARGINLEFT = 50, MARGINTOP = 100 + TOP;
public static final int W = 70;
public static final int CHESSW = 62;
// 14个格子,15根线
public static final int L = 15;
public static final int BLOCKL = 14;
public static final int BLACK = 2, WHITE = 1;
private int width = W * BLOCKL;
private int height = W * BLOCKL;
private int player;
private List<String> allList = new ArrayList<>();
private List<String> myList = new ArrayList<>();
private List<String> enemyList = new ArrayList<>();
private boolean canPlay;
private boolean isMove;
private Socket socket;
private int port;
private String ip;
private MainActivity mainActivity;
private PrintWriter pw;
private TextView tvTip;
private Button btnRestart;
public ClientView(Context context, String ip, int port, MainActivity mainActivity) {
super(context);
this.port = port;
this.ip = ip;
this.mainActivity = mainActivity;
initMap();
ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tvTip = new TextView(context);
tvTip.setText("连接中");
tvTip.setX(500);
tvTip.setY(20);
mainActivity.addContentView(tvTip, params);
btnRestart = new Button(context);
btnRestart.setText("重新开始");
btnRestart.setX(MARGINLEFT);
btnRestart.setY(20);
btnRestart.setEnabled(false);
mainActivity.addContentView(btnRestart, params);
btnRestart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
restartGame();
sendMes("restart");
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isMove = false;
break;
case MotionEvent.ACTION_MOVE:
isMove = true;
break;
case MotionEvent.ACTION_UP:
if (!canPlay) {
break;
}
if (!isMove) {
int x = (int) event.getX() - MARGINLEFT;
int y = (int) event.getY() - MARGINTOP;
if (x < -W / 2 || x > width + W / 2 || y < -W / 2 || y > width + W / 2) {
break;
}
// column
x = x / W + (x % W > W / 2 ? 1 : 0);
// row
y = y / W + (y % W > W / 2 ? 1 : 0);
String move = y + "|" + x;
if (allList.contains(move)) {
break;
}
allList.add(move);
myList.add(move);
sendMes("move|" + move);
canPlay = false;
tvTip.setText("对方下");
invalidate();
if (isWin()) {
Toast.makeText(getContext(), "白棋获胜!", Toast.LENGTH_SHORT).show();
tvTip.setText("我方获胜!");
sendMes("win");
}
}
}
return true;
}
});
}
public void startJoin() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
try {
socket = new Socket(ip, port);
setTip("已连接");
// 存储当前输入的 ip
mainActivity.setMyIp();
sendMes("join|");
new MyThread().start();
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0);
}
private boolean isWin() {
return isCanLink();
}
private boolean isCanLink() {
// 黑棋先,服务端为黑棋,客户端为白棋
// 判断最后下的是谁
int who = allList.size() % 2;
String[] t = allList.get(allList.size() - 1).split("\\|");
int r1 = Integer.valueOf(t[0]);
int c1 = Integer.valueOf(t[1]);
if (canVLink(who, r1, c1)) {
return true;
}
if (canHLink(who, r1, c1)) {
return true;
}
if (canLeftObliqueLink(who, r1, c1)) {
return true;
}
if (canRightObliqueLink(who, r1, c1)) {
return true;
}
return false;
}
private boolean canRightObliqueLink(int who, int r1, int c1) {
int count = 0;
int r2;
int c2;
if (who == 0) {
// left top
r2 = r1 - 1;
c2 = c1 - 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2--;
}
// right down
r2 = r1 + 1;
c2 = c1 + 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2++;
}
if (count >= 4) {
return true;
}
} else {
// right top
r2 = r1 - 1;
c2 = c1 - 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2--;
}
// left down
r2 = r1 + 1;
c2 = c1 + 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2++;
}
if (count >= 4) {
return true;
}
}
return false;
}
private boolean canLeftObliqueLink(int who, int r1, int c1) {
int count = 0;
int r2;
int c2;
if (who == 0) {
// right top
r2 = r1 - 1;
c2 = c1 + 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2++;
}
// left down
r2 = r1 + 1;
c2 = c1 - 1;
while (myList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2--;
}
if (count >= 4) {
return true;
}
} else {
// right top
r2 = r1 - 1;
c2 = c1 + 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2--;
c2++;
}
// left down
r2 = r1 + 1;
c2 = c1 - 1;
while (enemyList.contains(r2 + "|" + c2)) {
count++;
r2++;
c2--;
}
if (count >= 4) {
return true;
}
}
return false;
}
private boolean canHLink(int who, int r1, int c1) {
int count = 0;
int c2;
if (who == 0) {
// left
c2 = c1 - 1;
while (myList.contains(r1 + "|" + c2)) {
count++;
c2--;
}
// right
c2 = c1 + 1;
while (myList.contains(r1 + "|" + c2)) {
count++;
c2++;
}
if (count >= 4) {
return true;
}
} else {
// left
c2 = c1 - 1;
while (enemyList.contains(r1 + "|" + c2)) {
count++;
c2--;
}
// right
c2 = c1 + 1;
while (enemyList.contains(r1 + "|" + c2)) {
count++;
c2++;
}
if (count >= 4) {
return true;
}
}
return false;
}
private boolean canVLink(int who, int r1, int c1) {
int count = 0;
int r2;
if (who == 0) {
// top
r2 = r1 - 1;
while (myList.contains(r2 + "|" + c1)) {
count++;
r2--;
}
// down
r2 = r1 + 1;
while (myList.contains(r2 + "|" + c1)) {
count++;
r2++;
}
if (count >= 4) {
return true;
}
} else {
// top
r2 = r1 - 1;
while (enemyList.contains(r2 + "|" + c1)) {
count++;
r2--;
}
// down
r2 = r1 + 1;
while (enemyList.contains(r2 + "|" + c1)) {
count++;
r2++;
}
if (count >= 4) {
return true;
}
}
return false;
}
class MyThread extends Thread {
@Override
public void run() {
// move|r|c
// join|
// conn|
// quit
BufferedReader br = null;
InputStreamReader isr = null;
try {
String t;
while (true) {
sleep(100);
isr = new InputStreamReader(socket.getInputStream());
br = new BufferedReader(isr);
if (br.ready()) {
String cmd = br.readLine();
String[] array = cmd.split("\\|");
switch (array[0]) {
case "conn":
// 客户端一定为白棋
player = WHITE;
// 主机先下
canPlay = false;
setTip("对方下");
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
btnRestart.setEnabled(true);
Toast.makeText(mainActivity, "你是白棋", Toast.LENGTH_SHORT).show();
}
});
break;
case "move":
t = array[1] + "|" + array[2];
allList.add(t);
enemyList.add(t);
canPlay = true;
setTip("我下");
if (isWin()) {
post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "黑棋获胜!", Toast.LENGTH_SHORT).show();
tvTip.setText("对方获胜!");
canPlay = false;
}
});
}
invalidate();
break;
case "restart":
restartGame();
break;
case "win":
break;
case "quit":
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void sendMes(final String s) {
new Thread(new Runnable() {
@Override
public void run() {
try {
pw = new PrintWriter(socket.getOutputStream());
pw.println(s);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void initMap() {
allList.clear();
myList.clear();
enemyList.clear();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw background
Paint paint = new Paint();
paint.setColor(Color.parseColor("#FFE869"));
canvas.drawRect(0, TOP, 1080, 1400 + TOP, paint);
// draw line
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
for (int i = 0; i < L; i++) {
int hx = MARGINLEFT;
int hy = MARGINTOP + i * W;
int vx = MARGINLEFT + i * W;
int vy = MARGINTOP;
canvas.drawLine(hx, hy, MARGINLEFT + width, hy, paint);
canvas.drawLine(vx, vy, vx, MARGINTOP + height, paint);
}
RectF rectF = new RectF();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int w = 20;
int x = MARGINLEFT + W * 3 + j * W * 4 - w / 2;
int y = MARGINTOP + W * 3 + i * W * 4 - w / 2;
rectF.set(x, y, x + 20, y + 20);
canvas.drawOval(rectF, paint);
}
}
// draw chess
String[] t;
int r, c;
for (int i = 0; i < allList.size(); i++) {
if (i % 2 == 0) {
paint.setColor(Color.BLACK);
} else {
paint.setColor(Color.WHITE);
}
t = allList.get(i).split("\\|");
r = Integer.valueOf(t[0]);
c = Integer.valueOf(t[1]);
c = MARGINLEFT + c * W - CHESSW / 2;
r = MARGINTOP + r * W - CHESSW / 2;
rectF.set(c, r, c + CHESSW, r + CHESSW);
canvas.drawOval(rectF, paint);
}
}
private void setTip(final String s) {
post(new Runnable() {
@Override
public void run() {
tvTip.setText(s);
}
});
}
public void restartGame() {
allList.clear();
myList.clear();
enemyList.clear();
canPlay = false;
setTip("对方下");
post(new Runnable() {
@Override
public void run() {
invalidate();
}
});
}
}
到此,关于“Android如何实现五子棋游戏局域网版”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。