kotlin實(shí)現(xiàn)五子棋單機(jī)游戲
最近學(xué)了點(diǎn)kotlin的相關(guān)知識(shí),順手寫(xiě)了一個(gè)簡(jiǎn)單的五子棋單機(jī)游戲,分享給大家吧!有興趣的可以看看
五子棋界面
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 //白旗獲勝標(biāo)志
var bSuccess: Boolean = false //黑棋獲勝標(biāo)志
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 {
//記錄連續(xù)的棋子數(shù),湊成5個(gè)即一方獲勝
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
}
}
//一方獲勝,游戲結(jié)束
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
}
}
//一方獲勝,游戲結(jié)束
if (ln == 4) {
return true
}
//向左向右
return ln + rn >= 4
}
//縱向遍歷
fun verticalErgodic(data: Data, arry: List<Data>): Boolean {
//記錄連續(xù)的棋子數(shù),湊成5個(gè)即一方獲勝
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
}
}
//一方獲勝,游戲結(jié)束
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
}
//對(duì)角遍歷
fun acrossErgodic(data: Data, arry: List<Data>): Boolean {
var lt = 0 //左上方向連續(xù)棋子個(gè)數(shù)
var lb = 0 //左下方向連續(xù)棋子個(gè)數(shù)
var rt = 0 //右上方向連續(xù)棋子個(gè)數(shù)
var rb = 0 //右下方向連續(xù)棋子個(gè)數(shù)
//右下方向遍歷
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
}
//左上右下這條對(duì)角線
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
}
//左下右上這條對(duì)角線
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)
}
}
}
數(shù)據(jù)類
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
}
}
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android動(dòng)態(tài)添加碎片代碼實(shí)例
這篇文章主要介紹了Android動(dòng)態(tài)添加碎片代碼實(shí)例,2019-06-06
Android軟件啟動(dòng)動(dòng)畫(huà)及動(dòng)畫(huà)結(jié)束后跳轉(zhuǎn)的實(shí)現(xiàn)方法
這篇文章主要介紹了Android軟件啟動(dòng)動(dòng)畫(huà)及動(dòng)畫(huà)結(jié)束后跳轉(zhuǎn)的實(shí)現(xiàn)方法,實(shí)例分析了Android圖片播放及定時(shí)器的相關(guān)使用技巧,非常具有使用價(jià)值,需要的朋友可以參考下2015-10-10
設(shè)置Android設(shè)備WIFI在休眠時(shí)永不斷開(kāi)的代碼實(shí)現(xiàn)
這篇文章主要介紹了設(shè)置Android設(shè)備WIFI在休眠時(shí)永不斷開(kāi)的代碼實(shí)現(xiàn),需要的朋友可以參考下2014-07-07
Android ContentProvider查看/讀取手機(jī)聯(lián)系人實(shí)例
本篇文章主要介紹了Android ContentProvider查看/讀取手機(jī)聯(lián)系人實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
Android動(dòng)態(tài)模糊效果的快速實(shí)現(xiàn)方法
這篇文章主要介紹了Android動(dòng)態(tài)模糊效果的快速實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
Android clipChildren屬性實(shí)例詳解
本文主要介紹Android clipChildren的屬性,這里對(duì)clipChildren屬性做了一個(gè)小例子,展示了效果圖和實(shí)例代碼,方便大家觀看理解2016-07-07
Android新布局方式ConstraintLayout快速入門(mén)教程
谷歌在2016年的IO大會(huì)上推出的一種新的布局方式—-ConstraintLayout,這局是一種約束型的布局方式,下面這篇文章主要給大家介紹了Android中新布局方式ConstraintLayout的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-05-05
Android開(kāi)發(fā)導(dǎo)入項(xiàng)目報(bào)錯(cuò)Ignoring InnerClasses attribute for an anonym
今天小編就為大家分享一篇關(guān)于Android開(kāi)發(fā)導(dǎo)入項(xiàng)目報(bào)錯(cuò)Ignoring InnerClasses attribute for an anonymous inner class的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12

