中国象棋
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 id="title" style="text-align: center;">中国象棋</h1>
<script>
let title = document.getElementById("title")
let data = {title:"这不是象棋",gettitle:function(msg,arg){
console.log(this.title)
console.log(msg,arg)
}}
let data2 = {
title:"中国象棋"
}
data.gettitle.apply(data2,["消息",3])
data.gettitle.call(data2,"一段消息",1)
data.gettitle.bind(data2,"xiaoxi",4)()
setTimeout(()=>{
title.innerText = data.title
data.title = "中国象棋"
console.log(data)
},1000)
class Game{
constructor(id){
this.graph_size = 80
this.game_wrap = document.createElement("div")
this.game_wrap.id = id
this.game_wrap.style.position = "relative"
this.cur_player = "red"
this.cur_chess_role_list = []
this.cur_choose_chess_role = null
this.step_position_list = []
this.cur_step_position_list = []
this.chess_role_list = [
{constr:JiangShuai,color:"black",position:[4,0]},
{constr:JiangShuai,color:"red",position:[4,9]},
{constr:Shi,color:"black",position:[3,0]},
{constr:Shi,color:"black",position:[5,0]},
{constr:Shi,color:"red",position:[3,9]},
{constr:Shi,color:"red",position:[5,9]},
{constr:Xiang,color:"black",position:[2,0]},
{constr:Xiang,color:"black",position:[6,0]},
{constr:Xiang,color:"red",position:[2,9]},
{constr:Xiang,color:"red",position:[6,9]},
{constr:Ma,color:"black",position:[1,0]},
{constr:Ma,color:"black",position:[7,0]},
{constr:Ma,color:"red",position:[1,9]},
{constr:Ma,color:"red",position:[7,9]},
{constr:Ju,color:"black",position:[0,0]},
{constr:Ju,color:"black",position:[8,0]},
{constr:Ju,color:"red",position:[0,9]},
{constr:Ju,color:"red",position:[8,9]},
{constr:Pao,color:"black",position:[1,2]},
{constr:Pao,color:"black",position:[7,2]},
{constr:Pao,color:"red",position:[1,7]},
{constr:Pao,color:"red",position:[7,7]},
{constr:BingZu,color:"black",position:[0,3]},
{constr:BingZu,color:"black",position:[2,3]},
{constr:BingZu,color:"black",position:[4,3]},
{constr:BingZu,color:"black",position:[6,3]},
{constr:BingZu,color:"black",position:[8,3]},
{constr:BingZu,color:"red",position:[0,6]},
{constr:BingZu,color:"red",position:[2,6]},
{constr:BingZu,color:"red",position:[4,6]},
{constr:BingZu,color:"red",position:[6,6]},
{constr:BingZu,color:"red",position:[8,6]},
]
}
changePlayer(){
if(this.cur_player==="red"){
this.cur_player = "black"
}else{
this.cur_player = "red"
}
}
start(){
this.addChessGroundToWrap()
this.addChessRoleListToWrap()
this.addStepPositionToWrap()
}
changeGraphSize(size_num){
this.graph_size = size_num
}
addChessGroundToWrap(){
this.chessGroundElement = new ChessGround(this.graph_size).el
this.game_wrap.append(this.chessGroundElement)
}
addStepPositionToWrap(){
for(let i = 0;i<9;i++){
for(let j = 0;j<10;j++){
let position = [i,j]
let stepPosition = new StepPosition(this.graph_size,position)
this.step_position_list.push(stepPosition)
this.game_wrap.append(stepPosition.el)
stepPosition.el.addEventListener("click",()=>{
for(let i =0;i< this.cur_chess_role_list.length;i++){
if(this.cur_chess_role_list[i].position[0]===stepPosition.position[0]&&this.cur_chess_role_list[i].position[1]===stepPosition.position[1]&&this.cur_chess_role_list[i].status==="alive"){
this.cur_chess_role_list[i].removeChessSelf()
}
}
this.cur_choose_chess_role.changePosition(stepPosition.position)
this.clearAllAffect()
this.changePlayer()
let jiangshuai = this.cur_player==="red"?this.cur_chess_role_list[1]:this.cur_chess_role_list[0]
jiangshuai.checkAliveStatus(this.cur_chess_role_list)
})
}
}
}
clearAllAffect(){
if(!this.cur_choose_chess_role){
return
}
this.cur_choose_chess_role.chooseChessOrNot(false)
this.cur_choose_chess_role = null
for(let i =0;i< this.cur_step_position_list.length;i++){
this.cur_step_position_list[i].hide()
}
this.cur_step_position_list = []
}
addChessRoleListToWrap(){
this.initChessRoleList()
let groundEv = ()=>{
this.clearAllAffect()
this.chessGroundElement.onclick = ()=>{}
}
let clearAffect = () => {
groundEv()
}
for(let i = 0;i<this.cur_chess_role_list.length;i++){
let el = this.cur_chess_role_list[i].el
this.game_wrap.append(el)
el.addEventListener("click",()=>{
clearAffect()
this.cur_choose_chess_role = this.cur_chess_role_list[i]
this.cur_choose_chess_role.chooseChessOrNot(true)
if(this.cur_choose_chess_role.color!==this.cur_player){
alert("还没轮到你")
clearAffect()
return
}
let list = this.cur_choose_chess_role.getActiveStepPosition(this.cur_chess_role_list)
for(let i =0;i< list.length;i++){
for(let j=0; j< this.step_position_list.length;j++){
if(list[i][0]===this.step_position_list[j].position[0]&&list[i][1]===this.step_position_list[j].position[1]){
this.step_position_list[j].show()
this.cur_step_position_list.push(this.step_position_list[j])
}
}
}
this.chessGroundElement.onclick = groundEv
})
}
}
initChessRoleList(){
this.cur_chess_role_list = []
for(let i = 0;i<this.chess_role_list.length;i++){
let constr = this.chess_role_list[i].constr
let color = this.chess_role_list[i].color
let position = this.chess_role_list[i].position
let chess_role_instance = new constr(this.graph_size,color,position)
this.cur_chess_role_list.push(chess_role_instance)
}
}
removeChessRoleInstance(el){
for(let i =0;i< this.cur_chess_role_list.length;i++){
if(this.cur_chess_role_list[i].el===el){
this.cur_chess_role_list.splice(i,1,[])
}
}
this.cur_chess_role_list = this.cur_chess_role_list.filter((item)=>{
return item.length!==0
})
}
mount(){
document.body.append(this.game_wrap)
}
}
class ChessGround{
constructor(size){
this.el = document.createElement("canvas")
this.el.width = size * 9
this.el.height = size * 10
let ctx = this.el.getContext('2d')
ctx.strokeStyle = 'black'
for(let i = 0;i<10;i++){
ctx.beginPath()
ctx.moveTo(size/2,i*size+size/2)
ctx.lineTo((8+1/2)*size,(i+1/2)*size)
ctx.stroke()
}
for(let i = 0;i<9;i++){
ctx.beginPath()
ctx.moveTo((i+1/2)*size,size/2)
ctx.lineTo((i+1/2)*size,(9+1/2)*size)
ctx.stroke()
}
ctx.beginPath()
ctx.moveTo((3+1/2)*size,size/2)
ctx.lineTo((5+1/2)*size,(2+1/2)*size)
ctx.moveTo((5+1/2)*size,size/2)
ctx.lineTo((3+1/2)*size,(2+1/2)*size)
ctx.moveTo((3+1/2)*size,(7+1/2)*size)
ctx.lineTo((5+1/2)*size,(9+1/2)*size)
ctx.moveTo((5+1/2)*size,(7+1/2)*size)
ctx.lineTo((3+1/2)*size,(9+1/2)*size)
ctx.stroke()
ctx.clearRect(size/2+1,(4+1/2)*size+1,8*size-2,size-2)
}
}
class StepPosition {
constructor(size,position){
this.size = size
this.position = position
this.el = document.createElement("canvas")
this.el.instance = this
this.el.width = this.size/6
this.el.height = this.size/6
this.el.style.borderRadius = '50%'
this.el.style.backgroundColor = "red"
this.el.style.position = "absolute"
this.el.style.cursor = "pointer"
this.el.style.display = "none"
this.el.style.left = this.size/2 + this.position[0]*this.size - this.size/12+"px"
this.el.style.top = this.size/2 + this.position[1]*this.size - this.size/12 +"px"
}
show(){
this.el.style.display = "block"
}
hide(){
this.el.style.display = "none"
}
}
class ChessRole{
constructor(size,color,position){
this.size = size
this.color = color
this.position = position
this.el = document.createElement("canvas")
this.el.instance = this
this.el.width = this.size*3/4
this.el.height = this.size*3/4
this.el.style.borderRadius = '50%'
this.el.style.border = `1px solid ${this.color}`
this.el.style.backgroundColor = "white"
this.el.style.position = "absolute"
this.el.style.cursor = "pointer"
this.el.style.display = "block"
this.status = "alive"
this.el.style.left = this.size/2 + this.position[0]*this.size - this.size*3/8 +"px"
this.el.style.top = this.size/2 + this.position[1]*this.size - this.size*3/8 +"px"
this.ctx = this.el.getContext('2d')
this.ctx.font = `${this.el.width*(2/3)}px Arial`
this.ctx.textAlign = "center"
this.ctx.textBaseline = "middle"
this.ctx.fillStyle = this.color
}
removeChessSelf(){
this.el.style.display = "none"
this.status = "die"
}
chooseChessOrNot(flag){
if(flag){
this.el.style.border = `3px solid ${this.color}`
this.el.style.left = this.size/2 + this.position[0]*this.size - this.size*3/8 -2 +"px"
this.el.style.top = this.size/2 + this.position[1]*this.size - this.size*3/8 -2 +"px"
}else{
this.el.style.border = `1px solid ${this.color}`
this.el.style.left = this.size/2 + this.position[0]*this.size - this.size*3/8 +"px"
this.el.style.top = this.size/2 + this.position[1]*this.size - this.size*3/8 +"px"
}
}
changePosition(position){
this.position = position
this.el.style.left = this.size/2 + this.position[0]*this.size - this.size*3/8 +"px"
this.el.style.top = this.size/2 + this.position[1]*this.size - this.size*3/8 +"px"
}
}
class JiangShuai extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = (this.color==='black')?'将':'帅'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
steplist.push([this.position[0]-1,this.position[1]])
steplist.push([this.position[0]+1,this.position[1]])
steplist.push([this.position[0],this.position[1]-1])
steplist.push([this.position[0],this.position[1]+1])
if(this.color==="black"){
steplist = steplist.filter((item)=>{
return item[0]>=3&&item[0]<=5&&item[1]>=0&&item[1]<=2
})
}else{
steplist = steplist.filter((item)=>{
return item[0]>=3&&item[0]<=5&&item[1]>=7&&item[1]<=9
})
}
let new_cur_role_list = cur_role_list.filter((item)=>{
return item.color === this.color&&item.status==="alive"
})
for(let i =0;i<steplist.length;i++){
for(let j =0;j< new_cur_role_list.length;j++){
if((steplist[i][0]===new_cur_role_list[j].position[0])&&(steplist[i][1]===new_cur_role_list[j].position[1])){
steplist.splice(i,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
return steplist
}
checkAliveStatus(cur_role_list){
for(let i =0;i<cur_role_list.length;i++){
if(cur_role_list[i].status==="alive"&&cur_role_list[i].color!==this.color){
let positionList = cur_role_list[i].getActiveStepPosition(cur_role_list)
for(let j =0;j<positionList.length;j++){
if(positionList[j][0]===this.position[0]&&positionList[j][1]===this.position[1]){
alert("将军")
}
}
}
}
}
}
class Shi extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = '士'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
steplist.push([this.position[0]-1,this.position[1]-1])
steplist.push([this.position[0]+1,this.position[1]-1])
steplist.push([this.position[0]-1,this.position[1]+1])
steplist.push([this.position[0]+1,this.position[1]+1])
if(this.color==="black"){
steplist = steplist.filter((item)=>{
return item[0]>=3&&item[0]<=5&&item[1]>=0&&item[1]<=2
})
}else{
steplist = steplist.filter((item)=>{
return item[0]>=3&&item[0]<=5&&item[1]>=7&&item[1]<=9
})
}
let new_cur_role_list = cur_role_list.filter((item)=>{
return item.color === this.color&&item.status==="alive"
})
for(let i =0;i<steplist.length;i++){
for(let j =0;j< new_cur_role_list.length;j++){
if((steplist[i][0]===new_cur_role_list[j].position[0])&&(steplist[i][1]===new_cur_role_list[j].position[1])){
steplist.splice(i,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
return steplist
}
}
class Xiang extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = '象'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
steplist.push([this.position[0]-2,this.position[1]-2])
steplist.push([this.position[0]+2,this.position[1]-2])
steplist.push([this.position[0]-2,this.position[1]+2])
steplist.push([this.position[0]+2,this.position[1]+2])
for(let i = 0;i<cur_role_list.length;i++){
if(cur_role_list[i].status==="alive"){
let cur_position = cur_role_list[i].position
if(cur_position[0]===this.position[0]-1&&cur_position[1]===this.position[1]-1){
steplist.splice(0,1,[])
}else if(cur_position[0]===this.position[0]+1&&cur_position[1]===this.position[1]-1){
steplist.splice(1,1,[])
}else if(cur_position[0]===this.position[0]-1&&cur_position[1]===this.position[1]+1){
steplist.splice(2,1,[])
}else if(cur_position[0]===this.position[0]+1&&cur_position[1]===this.position[1]+1){
steplist.splice(3,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
if(this.color==="black"){
steplist = steplist.filter((item)=>{
return item[0]>=0&&item[0]<=8&&item[1]>=0&&item[1]<=4
})
}else{
steplist = steplist.filter((item)=>{
return item[0]>=0&&item[0]<=8&&item[1]>=5&&item[1]<=9
})
}
let new_cur_role_list = cur_role_list.filter((item)=>{
return item.color === this.color&&item.status==="alive"
})
for(let i =0;i<steplist.length;i++){
for(let j =0;j< new_cur_role_list.length;j++){
if((steplist[i][0]===new_cur_role_list[j].position[0])&&(steplist[i][1]===new_cur_role_list[j].position[1])){
steplist.splice(i,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
return steplist
}
}
class Ma extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = '馬'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
steplist.push([this.position[0]-1,this.position[1]-2])
steplist.push([this.position[0]+1,this.position[1]-2])
steplist.push([this.position[0]+2,this.position[1]-1])
steplist.push([this.position[0]+2,this.position[1]+1])
steplist.push([this.position[0]-1,this.position[1]+2])
steplist.push([this.position[0]+1,this.position[1]+2])
steplist.push([this.position[0]-2,this.position[1]+1])
steplist.push([this.position[0]-2,this.position[1]-1])
for(let i = 0;i<cur_role_list.length;i++){
if(cur_role_list[i].status==="alive"){
let cur_position = cur_role_list[i].position
if(cur_position[0]===this.position[0]&&cur_position[1]===this.position[1]-1){
steplist.splice(0,1,[])
steplist.splice(1,1,[])
}else if(cur_position[0]===this.position[0]+1&&cur_position[1]===this.position[1]){
steplist.splice(2,1,[])
steplist.splice(3,1,[])
}else if(cur_position[0]===this.position[0]&&cur_position[1]===this.position[1]+1){
steplist.splice(4,1,[])
steplist.splice(5,1,[])
}else if(cur_position[0]===this.position[0]-1&&cur_position[1]===this.position[1]){
steplist.splice(6,1,[])
steplist.splice(7,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
steplist = steplist.filter((item)=>{
return item[0]>=0&&item[0]<=8&&item[1]>=0&&item[1]<=9
})
let new_cur_role_list = cur_role_list.filter((item)=>{
return item.color === this.color&&item.status==="alive"
})
for(let i =0;i<steplist.length;i++){
for(let j =0;j< new_cur_role_list.length;j++){
if((steplist[i][0]===new_cur_role_list[j].position[0])&&(steplist[i][1]===new_cur_role_list[j].position[1])){
steplist.splice(i,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
return steplist
}
}
class Ju extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = '車'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
for(let i = this.position[0]-1;i>=0;i--){
let next_position = [i,this.position[1]]
let continueFlag = true
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
if(cur_role_list[j].color===this.color){
continueFlag = false
}else{
steplist.push(next_position)
continueFlag = false
}
break
}
}
if(continueFlag){
steplist.push(next_position)
}else{
break
}
}
for(let i = this.position[0]+1;i<=8;i++){
let next_position = [i,this.position[1]]
let continueFlag = true
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
if(cur_role_list[j].color===this.color){
continueFlag = false
}else{
steplist.push(next_position)
continueFlag = false
}
break
}
}
if(continueFlag){
steplist.push(next_position)
}else{
break
}
}
for(let i = this.position[1]-1;i>=0;i--){
let next_position = [this.position[0],i]
let continueFlag = true
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
if(cur_role_list[j].color===this.color){
continueFlag = false
}else{
steplist.push(next_position)
continueFlag = false
}
break
}
}
if(continueFlag){
steplist.push(next_position)
}else{
break
}
}
for(let i = this.position[1]+1;i<=9;i++){
let next_position = [this.position[0],i]
let continueFlag = true
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
if(cur_role_list[j].color===this.color){
continueFlag = false
}else{
steplist.push(next_position)
continueFlag = false
}
break
}
}
if(continueFlag){
steplist.push(next_position)
}else{
break
}
}
return steplist
}
}
class Pao extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = '炮'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
let continueFlag = 0
for(let i = this.position[0]-1;i>=0;i--){
let next_position = [i,this.position[1]]
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
continueFlag++
if(continueFlag===2){
if(this.color!==cur_role_list[j].color){
steplist.push(next_position)
}
}
break
}
}
if(continueFlag===0){
steplist.push(next_position)
}else if(continueFlag===1){
continue
}else{
break
}
}
continueFlag = 0
for(let i = this.position[0]+1;i<=8;i++){
let next_position = [i,this.position[1]]
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
continueFlag++
if(continueFlag===2){
if(this.color!==cur_role_list[j].color){
steplist.push(next_position)
}
}
break
}
}
if(continueFlag===0){
steplist.push(next_position)
}else if(continueFlag===1){
continue
}else{
break
}
}
continueFlag = 0
for(let i = this.position[1]-1;i>=0;i--){
let next_position = [this.position[0],i]
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
continueFlag++
if(continueFlag===2){
if(this.color!==cur_role_list[j].color){
steplist.push(next_position)
}
}
break
}
}
if(continueFlag===0){
steplist.push(next_position)
}else if(continueFlag===1){
continue
}else{
break
}
}
continueFlag = 0
for(let i = this.position[1]+1;i<=9;i++){
let next_position = [this.position[0],i]
for(let j = 0;j<cur_role_list.length;j++){
if(cur_role_list[j].status==="alive"&&cur_role_list[j].position[0]===next_position[0]&&cur_role_list[j].position[1]===next_position[1]){
continueFlag++
if(continueFlag===2){
if(this.color!==cur_role_list[j].color){
steplist.push(next_position)
}
}
break
}
}
if(continueFlag===0){
steplist.push(next_position)
}else if(continueFlag===1){
continue
}else{
break
}
}
return steplist
}
}
class BingZu extends ChessRole{
constructor(size,color,position){
super(size,color,position)
this.text = (this.color==='black')?'卒':'兵'
this.ctx.fillText(this.text,this.el.width/2,this.el.width/2)
}
getActiveStepPosition(cur_role_list){
let steplist = []
if((this.position[1]===3||this.position[1]===4)&&this.color==='black'){
steplist.push([this.position[0],this.position[1]+1])
}else if((this.position[1]===6||this.position[1]===5)&&this.color==='red'){
steplist.push([this.position[0],this.position[1]-1])
}else{
if(this.color==='black'){
steplist.push([this.position[0]-1,this.position[1]])
steplist.push([this.position[0]+1,this.position[1]])
steplist.push([this.position[0],this.position[1]+1])
}else{
steplist.push([this.position[0]-1,this.position[1]])
steplist.push([this.position[0]+1,this.position[1]])
steplist.push([this.position[0],this.position[1]-1])
}
}
steplist = steplist.filter((item)=>{
return item[0]>=0&&item[0]<=8&&item[1]>=0&&item[1]<=9
})
let new_cur_role_list = cur_role_list.filter((item)=>{
return item.color === this.color&&item.status==="alive"
})
for(let i =0;i<steplist.length;i++){
for(let j =0;j< new_cur_role_list.length;j++){
if((steplist[i][0]===new_cur_role_list[j].position[0])&&(steplist[i][1]===new_cur_role_list[j].position[1])){
steplist.splice(i,1,[])
}
}
}
steplist = steplist.filter((item)=>{
return item.length!==0
})
return steplist
}
}
let game = new Game('one')
game.start()
game.mount()
</script>
</body>
<style>
</style>
</html>
- 缺点:未完成绝杀判断,没有对战功能,单纯完成游戏基本功能