kotlin实现五子棋单机游戏
作者:一颗暗色星辰 发布时间:2022-10-16 03:20:09
标签:kotlin,五子棋
最近学了点kotlin的相关知识,顺手写了一个简单的五子棋单机游戏,分享给大家吧!有兴趣的可以看看
五子棋界面
package wjc.kotlintest
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
/**
* Created by wjc on 2019/12/9.
*/
class MyCustomView : View {
var paint: Paint = Paint()
var paintWhite: Paint = Paint()
var paintBlack: Paint = Paint()
val H: Int = 12
val V: Int = 12
var list = arrayListOf<Data>()//白子和黑子
var listW = arrayListOf<Data>()//白子
var listB = arrayListOf<Data>()//黑子
var wSuccess: Boolean = false //白旗获胜标志
var bSuccess: Boolean = false //黑棋获胜标志
init {
paintWhite.color = Color.WHITE
paintWhite.style = Paint.Style.FILL
paintBlack.color = Color.BLACK
paintBlack.style = Paint.Style.FILL
}
constructor(context: Context) : this(context, null)
constructor(context: Context, attr: AttributeSet?) : this(context, attr, 0)
constructor(context: Context, attr: AttributeSet?, defStyleAttr: Int) : super(context, attr, defStyleAttr)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val widthMode: Int = MeasureSpec.getMode(widthMeasureSpec)
val widthSize: Int = MeasureSpec.getSize(widthMeasureSpec)
val heightMode: Int = MeasureSpec.getMode(heightMeasureSpec)
val heightSize: Int = MeasureSpec.getSize(heightMeasureSpec)
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(760, 760)
} else if (widthMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(760, heightSize)
} else if (heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSize, 760)
}
}
override fun draw(canvas: Canvas?) {
super.draw(canvas)
for (i in 0..H) {
canvas!!.drawLine(20f, 20f + 60 * i, 740f, 20f + 60 * i, paint)
}
for (j in 0..V) {
canvas!!.drawLine(20f + 60 * j, 20f, 20f + 60 * j, 740f, paint)
}
if (listW.size != 0) {
for (item in listW) {
canvas!!.drawCircle(item.point.x * 60 + 20f, item.point.y * 60 + 20f, 15f, paintWhite)
}
}
if (listB.size != 0) {
for (item in listB) {
canvas!!.drawCircle(item.point.x * 60 + 20f, item.point.y * 60 + 20f, 15f, paintBlack)
}
}
}
fun addData(data: Data) {
if (list.size == 0) {
list.add(data)
listW.add(data)
return
}
if (!select(data)) {
list.add(data)
if (listW.size == listB.size) {
//白旗是否获胜
wSuccess = isSuccess(data, listW)
//白旗走
listW.add(data)
} else {
//黑棋是否获胜
bSuccess = isSuccess(data, listB)
//黑棋走
listB.add(data)
}
}
}
fun select(data: Data): Boolean {
for (item in list) {
if (data.equals(item))
return true
}
return false
}
fun isSuccess(data: Data, arry: List<Data>): Boolean {
return horizontalErgodic(data, arry) || verticalErgodic(data, arry) || acrossErgodic(data, arry)
}
//横向遍历
fun horizontalErgodic(data: Data, arry: List<Data>): Boolean {
//记录连续的棋子数,凑成5个即一方获胜
var rn = 0
var ln = 0
//向右遍历,y相同,x递增
for (i in 1..5) {
var _rn: Int = i
for (item in arry) {
if (data.point.y == item.point.y) {
if (data.point.x + i == item.point.x) {
rn++
break
}
}
}
if (_rn != rn) {
break
}
}
//一方获胜,游戏结束
if (rn == 4) {
return true
}
//向左遍历,y相同,x递减
for (i in 1..5) {
var _ln: Int = i
for (item in arry) {
if (data.point.y == item.point.y && data.point.x - i == item.point.x) {
ln++
break
}
}
if (_ln != ln) {
break
}
}
//一方获胜,游戏结束
if (ln == 4) {
return true
}
//向左向右
return ln + rn >= 4
}
//纵向遍历
fun verticalErgodic(data: Data, arry: List<Data>): Boolean {
//记录连续的棋子数,凑成5个即一方获胜
var tn = 0
var bn = 0
//向上遍历,x相同,y递增
for (i in 1..5) {
val _tn: Int = i
for (item in arry) {
if (data.point.x == item.point.x && data.point.y + i == item.point.y) {
tn++
break
}
}
if (_tn != tn) {
break
}
}
//一方获胜,游戏结束
if (tn == 4) {
return true
}
//向下遍历,x相同,y递减
for (i in 1..5) {
val _bn: Int = i
for (item in arry) {
if (data.point.x == item.point.x && data.point.y - i == item.point.y) {
bn++
break
}
}
if (_bn != bn) {
break
}
}
if (bn == 4) {
return true
}
//向左向右
return bn + tn >= 4
}
//对角遍历
fun acrossErgodic(data: Data, arry: List<Data>): Boolean {
var lt = 0 //左上方向连续棋子个数
var lb = 0 //左下方向连续棋子个数
var rt = 0 //右上方向连续棋子个数
var rb = 0 //右下方向连续棋子个数
//右下方向遍历
for (i in 1..5) {
val _rb: Int = i
for (item in arry) {
if (data.point.x + i == item.point.x && data.point.y + i == item.point.y) {
rb++
break
}
}
if (_rb != rb) {
break
}
}
if (rb == 4) {
return true
}
//左上方向遍历
for (i in 1..5) {
val _lt: Int = i
for (item in arry) {
if (data.point.x - i == item.point.x && data.point.y - i == item.point.y) {
lt++
break
}
}
if (_lt != lt) {
break
}
}
if (lt == 4) {
return true
}
//左上右下这条对角线
if (lt + rb >= 4) {
return true
}
//右上遍历
for (i in 1..5) {
val _rt: Int = i
for (item in arry) {
if (data.point.x + i == item.point.x && data.point.y - i == item.point.y) {
rt++
break
}
}
if (_rt != rt) {
break
}
}
if (rt == 4) {
return true
}
//左下遍历
for (i in 1..5) {
val _lb: Int = i
for (item in arry) {
if (data.point.x - i == item.point.x && data.point.y + i == item.point.y) {
lb++
break
}
}
if (_lb != lb) {
break
}
}
if (lb == 4) {
return true
}
//左下右上这条对角线
return lb + rt >= 4
}
fun reset() {
list.clear()
listW.clear()
listB.clear()
wSuccess = false
bSuccess = false
}
}
主界面
package wjc.kotlintest
import android.graphics.Point
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.MotionEvent
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
custom_view.setOnTouchListener { v, e ->
when (e.action) {
MotionEvent.ACTION_DOWN -> {
val x = e.x
val y = e.y
val x_n: Int = ((x - 20) / 60f + 0.5f).toInt()
val y_n: Int = ((y - 20) / 60f + 0.5f).toInt()
val data = Data(Point(x_n, y_n))
custom_view.addData(data)
custom_view.invalidate()
if (custom_view.wSuccess) {
Toast.makeText(this, "白旗获胜!", Toast.LENGTH_LONG).show()
custom_view.setEnabled(false)
} else if (custom_view.bSuccess) {
Toast.makeText(this, "黑棋获胜!", Toast.LENGTH_LONG).show()
custom_view.setEnabled(false)
}
}
}
return@setOnTouchListener true
}
reset.setOnClickListener {
custom_view.reset()
custom_view.invalidate()
custom_view.setEnabled(true)
}
}
}
数据类
package wjc.kotlintest
import android.graphics.Point
/**
* Created by wjc on 2019/12/10.
*/
data class Data(val point: Point) {
override fun equals(other: Any?): Boolean {
if (other is Data) {
if (point.x == other.point.x && point.y == other.point.y) {
return true
} else {
return false
}
} else {
return false
}
}
}
来源:https://blog.csdn.net/Chushiniudao/article/details/103498447


猜你喜欢
- 一、前言本文主要来介绍一个实际案例就是如何通过这个框架来修改系统的地理位置信息来实现隐藏功能,在如今社交工具的发展特别是微信,他有一个实时位
- 前言实现轨迹回放,GMap.NET有对应的类GMapRoute。这个类函数很少,功能有限,只能实现简单的轨迹回放。要实现更复杂的轨迹回放,就
- 背景数据之间两两趋势比较在数据分析应用中是非常常见的应用场景,如下所示:模拟考批次班级学生语文数学英语202302三年一班张小明130145
- 1、需求及配置需求:爬取京东手机搜索页面的信息,记录各手机的名称,价格,评论数等,形成一个可用于实际分析的数据表格。使用Maven项目,lo
- 概述从之前的配置里面我们可以看到我们的 URL 都是写死的,这不符合我们微服务的要求,我们微服务是只要知道服务的名字,根据名字去找,而直接写
- C#剪切板Clipboard类我们现在先来看一下官方文档的介绍位于:System.Windows.Forms 命名空间下Provides m
- 在进行C#程序设计时,用的最多的莫过于string了,但有些时候由于不仔细或者基础的不牢固等因素容易出错,今天本文就来较为详细的总结一下C#
- 一、排序1.获取DataTable的默认视图2.对视图设置排序表达式3.用排序后的视图导出的新DataTable替换就DataTable(A
- 前言微服务架构,前后端分离目前已成为互联网项目开发的业界标准,其核心思想就是前端(APP、小程序、H5页面等)通过调用后端的API接口,提交
- MyBatis if test 判断字符串相等不生效采用 MyBatis 框架操作 MySQL 数据库时,判断传入的字符串 priceFla
- 什么是粘包/拆包 一般所谓的TCP粘包是在一次接收数据不能完全地体现
- 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:给定 num
- 本文主要对SpringBoot2.x参数校验进行简单总结,其中SpringBoot使用的2.4.5版本。一、引入依赖<dependen
- JWT是什么JWT全称是Json Web Token,是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放
- 1. 新建TestServlet类package com.yanek.test;import java.io.IOException;imp
- Java非法字符: ‘\ufeff‘Java中项目启动出现 非法字符: '\ufeff
- BigDecimal 类一、 概述Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运
- 本文实例讲述了Android编程设计模式之中介者模式。分享给大家供大家参考,具体如下:一、介绍中介者模式(Mediator Pattern)
- 同步方法和异步方法的区别同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果异步方法则在被调用之后立即返回以便程序在被调用方法完成
- 1、maven打包Spring Boot项目的pom.xml文件中默认使用spring-boot-maven-plugin插件进行打包:&l