commit 2cd12146bc392382bf9ba4b3674e4235e75e71ab
parent 24c60df5d92316806393195ca04a128c43f4d804
Author: Cody Lewis <luxdotsugi@gmail.com>
Date: Mon, 6 Aug 2018 10:32:46 +1000
The web app now has a starting board
Diffstat:
11 files changed, 554 insertions(+), 6 deletions(-)
diff --git a/src/WebApp/Board.py b/src/WebApp/Board.py
@@ -0,0 +1,260 @@
+import re # regex
+import Piece
+from Functions import Direction
+class Board:
+ def __init__(self):
+ self.playBoard = dict()
+ self.rows = 8
+ self.columns = 8
+ for i in range(97, 98+self.rows): # letters for columns, with 'a' at the top and 'i' at the bottom
+ if(i == 97 or i == 98):
+ colour = 'B'
+ elif(i == 96 + self.rows or i == 97 + self.rows):
+ colour = 'W'
+ for j in range(1, self.columns+1): # numbers for rows, with 1 at the left and 8 at the right
+ index = str(chr(i)) + str(j)
+ if(i == 97 or i == 97 + self.rows): # essentially a factory method
+ if(j == 1 or j == 8):
+ self.playBoard[index] = Piece.Rook(0, True, colour, j)
+ elif(j == 2 or j == 7):
+ self.playBoard[index] = Piece.Knight(0, True, colour, j)
+ elif(j == 3 or j == 6):
+ self.playBoard[index] = Piece.Bishop(0, True, colour, j)
+ elif(j == 4):
+ self.playBoard[index] = Piece.Queen(0, True, colour, j)
+ else:
+ self.playBoard[index] = Piece.King(0, True, colour, j)
+ elif(i == 98 or i == 96 + self.rows):
+ self.playBoard[index] = Piece.Pawn(0, True, colour, j)
+ else:
+ self.playBoard[index] = '0'
+
+ def addMovement(self, i, move): # add an atomic movement unit to the index
+ if(move == Direction.UP):
+ i = chr(ord(i[0:1])-1) + str(int(i[1:]))
+ elif(move == Direction.DOWN):
+ i = chr(ord(i[0:1])+1) + str(int(i[1:]))
+ elif(move == Direction.RIGHT):
+ i = i[0:1] + str(int(i[1:])-1)
+ elif(move == Direction.LEFT):
+ i = i[0:1] + str(int(i[1:])+1)
+ elif(move == Direction.UPRIGHT):
+ i = chr(ord(i[0:1])-1) + str(int(i[1:])-1)
+ elif(move == Direction.DOWNRIGHT):
+ i = chr(ord(i[0:1])+1) + str(int(i[1:])-1)
+ elif(move == Direction.DOWNLEFT):
+ i = chr(ord(i[0:1])+1) + str(int(i[1:])+1)
+ else:
+ i = chr(ord(i[0:1])-1) + str(int(i[1:])+1)
+ return i
+
+ def play(self, start, end, colour, sp):
+ # check if inputs are valid
+ if(end != start and self.checkPoint(start) and self.checkPoint(end)):
+ if(self.playBoard[start] != '0'):
+ # check if colour matches
+ if(colour == self.playBoard[start].getId()[0:1]):
+ # evaluate the path travelled
+ dy = ord(start[0:1]) - ord(end[0:1]) # +ve: up, -ve: down
+ dx = int(start[1:]) - int(end[1:]) # +ve: right, -ve: left
+ movement = self.pathToString(dx, dy)
+ i = start
+ i = self.addMovement(i,movement[0:1])
+ if((self.playBoard[start].getId()[1:3] != "Kn" and (movement[0:1] in ['u', 'd', 'l', 'r'])) and i != end and self.playBoard[i] != '0'): # make sure nothing is in the way
+ return False
+ if(len(movement) > 1):
+ for j in range(1, len(movement)):
+ i = self.addMovement(i, movement[j : j + 1])
+ if(i != end and self.playBoard[i] != '0'): # check whether there are pieces in the way
+ return False
+ # output path as string into piece
+ if(self.playBoard[end] == '0'):
+ if(self.playBoard[start].canMove(movement)):
+ if(sp):
+ self.playBoard[start].superposition()
+ self.playBoard[end] = self.playBoard[start]
+ else:
+ self.playBoard[end] = self.playBoard[start]
+ self.playBoard[start] = '0'
+ return True
+ else:
+ return False
+ # check for attack
+ else: # ends at another piece
+ if(sp):
+ return False
+ if(self.playBoard[start].getId()[0 : 1] != self.playBoard[end].getId()[0 : 1]): # canMove function is contained in attack
+ # then do the attack
+ kill, supKill = self.playBoard[start].attack(self.playBoard[end], movement)
+ if(kill):
+ if(supKill):
+ self.findAndDestroyParent(end)
+ self.playBoard[end] = self.playBoard[start]
+ self.playBoard[start] = '0'
+ return True
+ return False
+ else:
+ return False
+ return False
+
+ def checkPoint(self, p): # check whether a point is on the board
+ charNum = ord(p[0 : 1])
+ if(charNum > 96 and charNum < 98 + self.rows):
+ num = int(p[1 : ])
+ if(num > 0 and num < 9):
+ return True
+ return False
+
+ def pathToString(self, dx, dy):
+ string = ''
+ if(dx > 0): # goes right
+ if(dy > 0): # goes up
+ if(dx == 2 and dy == 1): # L move
+ string = 'rq'
+ elif(dx == 1 and dy == 2):
+ string = 'uq'
+ elif(dx > dy):
+ diff = dx - dy
+ for _i in range(dy):
+ string = string + 'q'
+ for _i in range(diff):
+ string = string + 'r'
+ elif(dx < dy):
+ diff = dy - dx
+ for _i in range(dx):
+ string = string + 'q'
+ for _i in range(diff):
+ string = string + 'u'
+ else:
+ for _i in range(dx):
+ string = string + 'q'
+ elif(dy == 0):
+ for _i in range(dx):
+ string = string + 'r'
+ else: # goes down
+ if(dx == 2 and dy == -1):
+ string = 'rg'
+ elif(dx == 1 and dy == -2):
+ string = 'dg'
+ elif(dx > abs(dy)):
+ diff = dx - abs(dy) # dy is -ve
+ for _i in range(abs(dy)):
+ string = string + 'g'
+ for _i in range(diff):
+ string = string + 'r'
+ elif(dx < abs(dy)):
+ diff = abs(dy) - dx
+ for _i in range(dx):
+ string = string + 'g'
+ for _i in range(diff):
+ string = string + 'd'
+ else:
+ for _i in range(dx):
+ string = string + 'g'
+ elif(dx == 0):
+ if(dy > 0): # up
+ for _i in range(dy):
+ string = string + 'u'
+ else: # down (no change is an invalid input)
+ for _i in range(abs(dy)):
+ string = string + 'd'
+ else: # goes left
+ if(dy > 0): # goes up
+ if(dx == -2 and dy == 1): # L move
+ string = 'lf'
+ elif(dx == -1 and dy == 2):
+ string = 'uf'
+ elif(abs(dx) > dy):
+ diff = abs(dx) - dy
+ for _i in range(dy):
+ string = string + 'f'
+ for _i in range(diff):
+ string = string + 'l'
+ elif(abs(dx) < dy):
+ diff = dy - abs(dx)
+ for _i in range(abs(dx)):
+ string = string + 'f'
+ for _i in range(diff):
+ string = string + 'u'
+ else:
+ for _i in range(abs(dx)):
+ string = string + 'f'
+ elif(dy == 0):
+ for _i in range(abs(dx)):
+ string = string + 'l'
+ else: # goes down
+ if(dx == -2 and dy == -1):
+ string = 'lh'
+ elif(dx == -1 and dy == -2):
+ string = 'dh'
+ elif(abs(dx) > abs(dy)):
+ diff = abs(dx) - abs(dy) # dy is -ve
+ for _i in range(abs(dy)):
+ string = string + 'h'
+ for _i in range(diff):
+ string = string + 'l'
+ elif(abs(dx) < abs(dy)):
+ diff = abs(dy) - abs(dx)
+ for _i in range(abs(dx)):
+ string = string + 'h'
+ for _i in range(diff):
+ string = string + 'd'
+ else:
+ for _i in range(abs(dx)):
+ string = string + 'h'
+ return string
+
+ def findAndDestroyParent(self, point):
+ # search board for all matching pieces and destroy them
+ ident = self.playBoard[point].getId() # identifier
+ num = int(ident[len(ident) - 1 : len(ident)])
+ parent = ident[0 : len(ident) - 1] + '.'
+ for i in range(97, 98 + self.rows):
+ for j in range(1, self.columns + 1):
+ index = chr(i) + str(j)
+ if(self.playBoard[index] != '0'):
+ if(index != point and re.match(parent, self.playBoard[index].getId())):
+ otherId = self.playBoard[index].getId()
+ otherNum = int(otherId[len(otherId) - 1 : len(otherId)])
+ if(otherNum >= num):
+ self.playBoard[index] = '0'
+
+ def win(self): # find if one of the players have no Pieces left
+ blackWin = True
+ bkPat = 'BKi.*'
+ whiteWin = True
+ wkPat = 'WKi.*'
+ for i in range(97, 98 + self.rows):
+ for j in range(1, self.columns + 1):
+ index = chr(i) + str(j)
+ if(self.playBoard[index] != '0'):
+ currId = self.playBoard[index].getId()
+ if(re.match(bkPat, currId)):
+ whiteWin = False
+ elif(re.match(wkPat, currId)):
+ blackWin = False
+ if(whiteWin):
+ return 'W'
+ elif(blackWin):
+ return 'B'
+ else:
+ return '0'
+
+ def toString(self):
+ string = ''
+ for i in range(97, 99 + self.rows): # iterate through the letter part of the index
+ if(i < 98 + self.rows):
+ string = string + chr(i)
+ string = string + ' '
+ for j in range(1, self.columns+1):
+ index = str(chr(i)) + str(j)
+ if(i == 98 + self.rows):
+ string = string + ' ' + str(j)
+ elif(self.playBoard[index] == '0'):
+ string = string + '| '
+ else:
+ idTag = self.playBoard[index].getId()[ : 3]
+ string = string + '|' + idTag
+ if(i < 98+self.rows): # put a pipe at the end of the line
+ string = string + '|\n'
+ return string
diff --git a/src/WebApp/Functions.py b/src/WebApp/Functions.py
@@ -0,0 +1,55 @@
+from enum import Enum
+from qiskit import QuantumProgram
+def evalQubit(qrNo): # check if the most occurring qubit is all ones
+ qp = QuantumProgram()
+ try:
+ qr = qp.create_quantum_register("qr", qrNo)
+ cr = qp.create_classical_register("cr", qrNo)
+ qc = qp.create_circuit("superposition", [qr], [cr])
+
+ isPiece = ''
+ for i in range(qrNo):
+ qc.h(qr[i])
+ isPiece = isPiece + '1'
+ qc.measure(qr, cr)
+ result = qp.execute(["superposition"], backend="local_qasm_simulator", shots=1024)
+ counts = result.get_counts("superposition")
+ return isPiece == getGreatestCount(qrNo, counts)
+ except QISKITError as ex:
+ print("There was an error in the circuit! Error = {}".format(ex))
+ except RegisterSizeError as ex:
+ print("Error in the number of registers! Error = {}".format(ex))
+
+def getGreatestCount(qrNo, counts):
+ # increment throught dict, find greatest value, return index
+ greatestCount = ''
+ gc = 0
+ perms = 2**qrNo
+ for i in range(0, perms):
+ index = bin(i)[2:]
+ if len(index) < qrNo:
+ while len(index) < qrNo:
+ index = '0' + index
+ if counts[index] > gc:
+ greatestCount = index
+ gc = counts[index]
+ return greatestCount
+
+def splitMovement(movement):
+ # split the string movement into individual characters and store them in the returned array
+ # movement key: f = up dia left, u = up, q = up dia right, r = right, l = left, h = down dia left, d = down, g = down dia right
+ # Note: The move movement directions are from a birds eye view with the white pieces on the bottom
+ moveArr = []
+ for i in range(len(movement)):
+ moveArr.append(movement[i:i+1])
+ return moveArr
+
+class Direction(Enum):
+ UPLEFT = "f"
+ UP = "u"
+ UPRIGHT = "q"
+ RIGHT = "r"
+ LEFT = "l"
+ DOWN = "d"
+ DOWNLEFT = "h"
+ DOWNRIGHT = "g"
diff --git a/src/WebApp/Main.py b/src/WebApp/Main.py
@@ -1,4 +1,5 @@
-from qiskit import QuantumProgram
+# import Board
+# from qiskit import QuantumProgram
from flask import (
Blueprint, render_template, url_for, redirect, current_app, g, session, request, flash
)
@@ -10,4 +11,7 @@ def index():
@bp.route("/home")
def home():
- return render_template("index.html")-
\ No newline at end of file
+ return render_template("index.html")
+
+# def create_board():
+# return Board.Board()+
\ No newline at end of file
diff --git a/src/WebApp/Piece.py b/src/WebApp/Piece.py
@@ -0,0 +1,161 @@
+import Functions
+from Functions import Direction
+class Piece:
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ self.superposNo = superposNum
+ self.firstSuperPos = frstSuperPos
+ self.colour = col
+ self.idTag = self.colour + idT
+
+ def getId(self):
+ return self.idTag
+
+ def getSuperPosNum(self):
+ return self.superposNo
+
+ def superposition(self):
+ self.superposNo += 1
+ self.idTag = self.idTag + str(self.superposNo)
+ if self.firstSuperPos:
+ self.firstSuperPos = False
+
+ def attack(self, enemy, movement):
+ if self.canAttack(movement):
+ return enemy.die()
+ else:
+ return False, False
+
+ def canAttack(self, movement):
+ return self.canMove(movement)
+
+ def die(self):
+ if self.superposNo > 0:
+ return True, self.observe()
+ return True, False
+
+ def observe(self):
+ # check the Qubit stored in this piece
+ return Functions.evalQubit(self.superposNo)
+
+class Pawn(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'P ' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+ self.firstMove = True
+
+ def canMove(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ if(self.firstMove):
+ moveNum = 2
+ self.firstMove = False
+ else:
+ moveNum = 1
+ if(len(moveArr) <= moveNum):
+ if(self.colour == 'W'):
+ direction = Direction.UP
+ else:
+ direction = Direction.DOWN
+ for i in range(len(moveArr)):
+ if(not moveArr[i] == direction):
+ return False
+ return True
+ return False
+
+ def canAttack(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ if(self.colour == 'W'):
+ dir1 = Direction.UPLEFT
+ dir2 = Direction.UPRIGHT
+ else:
+ dir1 = Direction.DOWNLEFT
+ dir2 = Direction.DOWNRIGHT
+ if(len(moveArr) == 1 and (moveArr[0] == dir1 or moveArr[0] == dir2)):
+ return True
+ else:
+ return False
+
+class Bishop(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'B ' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+
+ def canMove(self,movement):
+ moveArr = Functions.splitMovement(movement)
+ direction = moveArr[0]
+ if direction in [Direction.UPLEFT, Direction.UPRIGHT, Direction.DOWNLEFT, Direction.DOWNRIGHT]:
+ for i in range(1, len(moveArr)):
+ if(direction != moveArr[i]):
+ return False
+ return True
+ return False
+
+class King(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'Ki' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+
+ def canMove(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ direction = moveArr[0]
+ if(len(moveArr) == 1):
+ if direction in [Direction.DOWN, Direction.UP, Direction.RIGHT, Direction.LEFT, Direction.DOWNRIGHT, Direction.DOWNLEFT, Direction.UPRIGHT, Direction.UPLEFT]:
+ return True
+ return False
+
+class Knight(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'Kn' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+
+ def canMove(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ if(len(moveArr) == 2): # need the L movement
+ if(self.__isL(moveArr)):
+ return True
+ return False
+
+ def __isL(self, moveArr):
+ if(moveArr[0] == Direction.UP):
+ if(moveArr[1] == Direction.UPLEFT or moveArr[1] == Direction.UPRIGHT):
+ return True
+ elif(moveArr[0] == Direction.DOWN):
+ if(moveArr[1] == Direction.DOWNLEFT or moveArr[1] == Direction.DOWNRIGHT):
+ return True
+ elif(moveArr[0] == Direction.LEFT):
+ if(moveArr[1] == Direction.UPLEFT or moveArr[1] == Direction.DOWNLEFT):
+ return True
+ elif(moveArr[0] == Direction.RIGHT):
+ if(moveArr[1] == Direction.UPRIGHT or moveArr[1] == Direction.DOWNRIGHT):
+ return True
+ else:
+ return False
+
+class Queen(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'Q ' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+
+ def canMove(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ direction = moveArr[0]
+ if direction in [Direction.DOWN, Direction.UP, Direction.RIGHT, Direction.LEFT, Direction.DOWNRIGHT, Direction.DOWNLEFT, Direction.UPRIGHT, Direction.UPLEFT]:
+ for i in range(1, len(moveArr)):
+ if(direction != moveArr[i]):
+ return False
+ return True
+ return False
+
+class Rook(Piece):
+ def __init__(self, superposNum, frstSuperPos, col, idT):
+ idT = 'R ' + str(idT)
+ Piece.__init__(self, superposNum, frstSuperPos, col, idT)
+
+ def canMove(self, movement):
+ moveArr = Functions.splitMovement(movement)
+ direction = moveArr[0]
+ if direction in [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT]:
+ for i in range(1, len(moveArr)):
+ if direction != moveArr[i]:
+ return False
+ return True
+ return False
diff --git a/src/WebApp/__pycache__/Board.cpython-36.pyc b/src/WebApp/__pycache__/Board.cpython-36.pyc
Binary files differ.
diff --git a/src/WebApp/__pycache__/Functions.cpython-36.pyc b/src/WebApp/__pycache__/Functions.cpython-36.pyc
Binary files differ.
diff --git a/src/WebApp/__pycache__/Main.cpython-36.pyc b/src/WebApp/__pycache__/Main.cpython-36.pyc
Binary files differ.
diff --git a/src/WebApp/__pycache__/Piece.cpython-36.pyc b/src/WebApp/__pycache__/Piece.cpython-36.pyc
Binary files differ.
diff --git a/src/WebApp/static/css/style.css b/src/WebApp/static/css/style.css
@@ -2,3 +2,29 @@
background: linear-gradient(rgb(0, 72, 0), rgb(28, 100, 28), rgb(56, 128, 56), rgb(84, 156, 84), rgb(255, 255, 255));
background-repeat: no-repeat;
}
+
+div.square {
+ height: 50px;
+ border: 1px solid black;
+ text-align: center;
+}
+
+div.square:hover {
+ background-color: rgb(146, 255, 255) !important;
+}
+
+div.move-space {
+ background-color: rgb(252, 118, 118) !important;
+}
+
+.piece {
+ font-size: 150%;
+}
+
+.pc-black {
+ color: red;
+}
+
+.pc-white {
+ color: blue;
+}
diff --git a/src/WebApp/templates/base.html b/src/WebApp/templates/base.html
@@ -21,6 +21,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+ <!-- Font awesome -->
+ <script defer src="https://use.fontawesome.com/releases/v5.2.0/js/all.js" integrity="sha384-4oV5EgaV02iISL2ban6c/RmotsABqE4yZxZLcYMAdG7FAPsyHYAPpywE9PJo+Khy" crossorigin="anonymous"></script>
{% block scripts %}{% endblock %}
</head>
<body class="bg-img">
diff --git a/src/WebApp/templates/index.html b/src/WebApp/templates/index.html
@@ -8,10 +8,50 @@
{% block contents %}
<div class="container-fluid bg-light">
+ <br />
<div class="container">
- <!-- <h1 class="display-1">Quantum Chess</h1> -->
- <!-- <canvas class="col-12" id="qccanvas"></canvas> -->
- <div id="board" class="col-12"></div>
+ <div class="container" id="board">
+ {% for i in range(0, 8) %}
+ <div class="row">
+ <div class="col-sm-2"></div>
+ {% for j in range(0, 8) %}
+ <div class="col-1
+ {% if ((j % 2) == (i % 2)) %}
+ bg-dark
+ {% else %}
+ bg-light
+ {% endif %}
+ square" id="{{ "ABCDEFGH"[i] }}{{ j + 1 }}">
+ {% if i in [0, 1, 6, 7] %}
+ <span class="piece text-center fa
+ {% if i in [0, 7] %}
+ {% if j in [0, 7] %}
+ fa-chess-rook
+ {% elif j in [1, 6] %}
+ fa-chess-knight
+ {% elif j in [2, 5] %}
+ fa-chess-bishop
+ {% elif j == 3 %}
+ fa-chess-queen
+ {% else %}
+ fa-chess-king
+ {% endif %}
+ {% else %}
+ fa-chess-pawn
+ {% endif %}
+ {% if i in [0, 1] %}
+ pc-black
+ {% else %}
+ pc-white
+ {% endif %}
+ "></span>
+ {% endif %}
+ </div>
+ {% endfor %}
+ <div class="col-sm-2"></div>
+ </div>
+ {% endfor %}
+ </div>
</div>
</div>
{% endblock %}
\ No newline at end of file