vitogit / vue-chessboard

Chessboard vue component to load positions, create positions and see threats
http://vitomd.com/vue-chessboard-examples/
GNU General Public License v3.0
165 stars 49 forks source link

Unable to couple chess AI #12

Closed dinuta closed 4 years ago

dinuta commented 4 years ago

Hi man,

I think your work is incomplete. There is no documentation about how you can write your own chess algorithm to play against. And frakly seeing your exposed API I didn't see how to proceed.

I wanted to follow this article but I couldn't: https://www.freecodecamp.org/news/simple-chess-ai-step-by-step-1d55a9266977/

To do so, I have to take this code and modify it as per those examples.

I don't know the initial scope you defined but this definitely is a good feature where people can learn chess algorithms and improve their knowledge of chess.

Cheers Catalin

vitogit commented 4 years ago

Hi, yes the scope is pretty minimal "load positions, create positions and see threats". You can fork the code and modify the internals (chessboard.vue) to get what you want. Like this https://github.com/vitogit/chess-notebook/blob/ee6b715c3a111f76d577a8ac63d1d925096a7137/src/components/chessboard.vue internally it uses https://github.com/ornicar/chessground the important part is

      this.board.set({
        movable: { events: { after: this.userPlay()} },
      })

that listen to the player move and then reprint the board. You can add a random opponent in the afterMove method like a simple random selected move.

              move = x  // select a random move from the possibleMoves() moves
              this.game.move(move) // make the move
              this.board.set({ // print the board
                fen: this.game.fen()
              })
              if (this.isFinished() ) {
                return
              }
dinuta commented 4 years ago

Hi @vitogit ,

Is it possible to create a new version where you expose the game & chessboard objects, so the user can pick it up from the vue instance?

That would bring a lot of value.

vitogit commented 4 years ago

I was thinking something like that, sounds like a good idea. When I have some free time I will try it, thanks for the suggestion.

dinuta commented 4 years ago

Hi @vitogit,

I think you did not have time to sketch something ...

I understand that this feature means feature, testing and documentation/examples.

What are your thoughts?

vitogit commented 4 years ago

I was investigating different methods that Vuejs provides to expose methods from components/plugins: mixins, composite and extend. I think the most flexible method is extend. It does not require changes in the current component. It works like this:

You create a new component that extends the chessboard component, then you can access the this.game or this.board in the created or mounted methods. Also you can override methods. So you can override the

<template>
  <div id="app">
    <h1>Simple Chessboard with legal moves</h1>
    <newboard/>
  </div>
</template>

<script>
import Vue from 'vue'
import { chessboard } from 'vue-chessboard'
import 'vue-chessboard/dist/vue-chessboard.css'

// Create a new component that extends the vue-chessboard
const newboard = Vue.component('newboard', {
  extends: chessboard,
  methods: {
    // loadPosition() {
    //   // console.log("override the loadPosition method________",this.game)
    // }
  },
  created() {
    console.log("this.game from create________",this.game)
  },
  mounted() {
    console.log("this.game from mounted________",this.game)
  }
})

Fully functional play vs random engine

Probably will add this example in the readme

import { chessboard } from 'vue-chessboard'
import 'vue-chessboard/dist/vue-chessboard.css'
import Vue from 'vue'

const newboard = Vue.component('newboard', {
  extends: chessboard,
  methods: {
    userPlay() {
      return (orig, dest) => {
        if (this.isPromotion(orig, dest)) {
          this.promoteTo = this.onPromotion()
        }
        this.game.move({from: orig, to: dest, promotion: this.promoteTo}) // promote to queen for simplicity
        this.board.set({
          fen: this.game.fen()
        })
        this.calculatePromotions()
        this.aiNextMove()
      };
    },
    aiNextMove() {
      let moves = this.game.moves({verbose: true})
      let randomMove = moves[Math.floor(Math.random() * moves.length)]
      this.game.move(randomMove)

      this.board.set({
        fen: this.game.fen(),
        turnColor: this.toColor(),
        movable: {
          color: this.toColor(),
          dests: this.possibleMoves(),
          events: { after: this.userPlay()},
        }
      });
    },
  },
  mounted() {
    this.board.set({
      movable: { events: { after: this.userPlay()} },
    })
  }
})

Example code https://github.com/vitogit/vue-chessboard-examples/blob/master/src/newboard.vue Playable (last example) http://vitomd.com/vue-chessboard-examples/

Option 2: Another option, not sure how useful it is but maybe helps like an idea is that you can access the component directly like this to override methods, props, etc

    chessboard.methods.loadPosition = ()=>{
      console.log('method overrided')
    }
    chessboard.props.fen = ()=>{
      console.log('prop overrided')
    }

OPTION 3: Also you can access the instance directly using refs. You can do something like

    <chessboard ref="chessboard1"/>
  mounted() {
    console.log("this.$refs.chessboard1.board________",this.$refs.chessboard1.board)
    console.log("this.$refs.chessboard1.game________",this.$refs.chessboard1.game)
  }

Hope some of the ideas helps you

dinuta commented 4 years ago

Hi @vitogit,

The extends looks good in my opinion and is more intuitive like generalist OOP languages.

From what I understand the npm artifact will remain as it is, and you will only provide AI example in the docs, thus meaning the component extend will remain as developer's own task.

Am I right?

dinuta commented 4 years ago

Another input that I must give you to make this even better:

I don't anything in mind, perhaps REST, FILES, other protocols if you are familiar to.

vitogit commented 4 years ago

Yes, the developer can extend as he likes and I think is how Vue.js have to be used using components.

I don't have much experience with engines on servers but it seems that you are describing a bot (and bot interface). Lichess has an API and different integrations (javascript, python, etc), but I'm not into it https://lichess.org/blog/WvDNticAAMu_mHKP/welcome-lichess-bots . Here is an implementation in javascript https://github.com/tailuge/bot-o-tron

This is out of the scope for this project, but anyone can extend or create a new package including those feature.

dinuta commented 4 years ago

Thanks @vitogit . Integrated this solution in my own vue cli project.

I will close this.

dinuta commented 4 years ago

Code: https://github.com/dinuta/vue-chess-server Playable at: https://vue-chess-server.herokuapp.com/

vitogit commented 4 years ago

That's really cool @dinuta