forked from cwtch.im/ui
Puzzle Game
This commit is contained in:
parent
9787e9292a
commit
b39157b338
|
@ -70,7 +70,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
if (msg.o != 2) return
|
if (msg.o != 2) return
|
||||||
|
|
||||||
if (msg.t != undefined) {
|
if (msg.t != undefined && msg.b != undefined) {
|
||||||
jsonModel4.insert(0,{
|
jsonModel4.insert(0,{
|
||||||
"title":msg.t,
|
"title":msg.t,
|
||||||
"body": msg.b,
|
"body": msg.b,
|
||||||
|
|
|
@ -1,18 +1,260 @@
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick 2.7
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 2.4
|
import QtQuick.Controls 2.4
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Material 2.0
|
import QtQuick.Controls.Material 2.0
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
import "../widgets"
|
import "../widgets"
|
||||||
import "../widgets/controls" as Awesome
|
import "../widgets/controls" as Awesome
|
||||||
import "../fonts/Twemoji.js" as T
|
import "../fonts/Twemoji.js" as T
|
||||||
|
import "../utils.js" as Utils
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
width:parent.width
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
id: puzzleGame
|
||||||
|
|
||||||
|
|
||||||
ScalingLabel {
|
Connections {
|
||||||
text: "gardening game or maybe some other cool cwtch-enabled game"
|
target: gcd
|
||||||
}
|
|
||||||
|
onClearMessages: function() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) {
|
||||||
|
var msg
|
||||||
|
try {
|
||||||
|
msg = JSON.parse(message)
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (msg.o != 3) return
|
||||||
|
|
||||||
|
if (msg.p != undefined && msg.s != undefined) {
|
||||||
|
|
||||||
|
var points = JSON.stringify(msg.s)
|
||||||
|
var path = JSON.stringify(msg.p)
|
||||||
|
|
||||||
|
var remove = -1
|
||||||
|
for(var i=0;i<solutions.count;i++) {
|
||||||
|
var puzzleName = "Puzzle " + points
|
||||||
|
console.log("Checking Solution " + puzzleName)
|
||||||
|
|
||||||
|
if (puzzleName == solutions.get(i).text) {
|
||||||
|
if (Utils.scorePath(JSON.parse(path)) < Utils.scorePath(JSON.parse(solutions.get(i).path))) {
|
||||||
|
remove = i
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove > -1) {
|
||||||
|
solutions.remove(remove)
|
||||||
|
console.log("Better solution found for Puzzle " + "Puzzle " + JSON.stringify(msg.s))
|
||||||
|
|
||||||
|
}
|
||||||
|
solutions.insert(0,{
|
||||||
|
"text": "Puzzle " + JSON.stringify(msg.s),
|
||||||
|
"points":points,
|
||||||
|
"path": path,
|
||||||
|
"from": from,
|
||||||
|
"displayName": displayName,
|
||||||
|
"timestamp": ts
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: solutions
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
width: 200
|
||||||
|
textRole: "text"
|
||||||
|
model: solutions
|
||||||
|
onActivated: {
|
||||||
|
console.log("Loading puzzle " + index)
|
||||||
|
var solution = solutions.get(index)
|
||||||
|
console.log("Loading puzzle " + JSON.parse(solution.path))
|
||||||
|
canvas.points = JSON.parse(solution.points)
|
||||||
|
canvas.path = JSON.parse(solution.path)
|
||||||
|
gameScore.text = Utils.scorePath(canvas.path)
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: gameDifficulty
|
||||||
|
value: 5
|
||||||
|
stepSize: 1.0
|
||||||
|
minimumValue: 4.0
|
||||||
|
maximumValue: 16.0
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleButton { // New Game
|
||||||
|
id: btnNewGame
|
||||||
|
icon: "regular/paper-plane"
|
||||||
|
text: "new game"
|
||||||
|
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
|
||||||
|
property int nextMessageID: 1
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
/**if (newposttitle.text != "" && newpostbody.text != "") {
|
||||||
|
var msg = JSON.stringify({"o":2, "t":newposttitle.text, "b":newpostbody.text})
|
||||||
|
gcd.sendMessage(msg, nextMessageID++)
|
||||||
|
}
|
||||||
|
newposttitle.text = ""
|
||||||
|
newpostbody.text = ""**/
|
||||||
|
canvas.points = []
|
||||||
|
canvas.path = []
|
||||||
|
gameScore.text = 0
|
||||||
|
for(var i=0;i<gameDifficulty.value;i++) {
|
||||||
|
canvas.points.push(Utils.getRandomInt(0,256))
|
||||||
|
}
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Canvas {
|
||||||
|
id: canvas
|
||||||
|
|
||||||
|
width: 640
|
||||||
|
height: 640
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
|
||||||
|
property var points : []
|
||||||
|
property var path : []
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for(var i=0;i<5;i++) {
|
||||||
|
points.push(Utils.getRandomInt(0,256))
|
||||||
|
console.log("POINTS" + points)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPaint: {
|
||||||
|
var context = getContext("2d")
|
||||||
|
|
||||||
|
var gridSize = 40
|
||||||
|
|
||||||
|
context.beginPath()
|
||||||
|
context.fillStyle = "#FFFFFFFF"
|
||||||
|
context.fillRect(0,0,1000,1000)
|
||||||
|
context.fill()
|
||||||
|
context.beginPath()
|
||||||
|
context.strokeStyle = "#000000"
|
||||||
|
context.fillStyle = "#800880"
|
||||||
|
context.lineWidth = 1
|
||||||
|
for(var x=0; x< 16;x++ ){
|
||||||
|
for(var y=0; y< 16;y++ ){
|
||||||
|
var inPoints = Utils.isGridOccupied(x,y,points)
|
||||||
|
if (inPoints == true) {
|
||||||
|
context.fillRect(x*gridSize,y*gridSize,gridSize, gridSize)
|
||||||
|
} else {
|
||||||
|
context.rect(x*gridSize,y*gridSize, gridSize, gridSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.stroke()
|
||||||
|
context.beginPath()
|
||||||
|
context.strokeStyle = "#FFFFFFFF"
|
||||||
|
context.font = "20px sans-serif"
|
||||||
|
for(var i=0;i<=path.length;i++) {
|
||||||
|
context.strokeText(i, (Math.floor(path[i]/16) * gridSize)+15, ((path[i] % 16)*gridSize) + 25)
|
||||||
|
}
|
||||||
|
context.stroke()
|
||||||
|
context.beginPath()
|
||||||
|
//context.strokeStyle = "#000000"
|
||||||
|
//var point = (mymouse.arrpoints["x"]*16)+mymouse.arrpoints["y"]
|
||||||
|
//context.strokeText(mymouse.arrpoints["x"] + " , " + mymouse.arrpoints["y"] + " = " + point, 10,560)
|
||||||
|
context.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mymouse
|
||||||
|
anchors.fill: parent
|
||||||
|
property var arrpoints : {"x": 1, "y": 1}
|
||||||
|
onClicked: {
|
||||||
|
arrpoints = Utils.mouseToGrid(mouseX, mouseY)
|
||||||
|
var point = (mymouse.arrpoints["x"]*16)+mymouse.arrpoints["y"]
|
||||||
|
var inPoints = Utils.isGridOccupied(mymouse.arrpoints["x"], mymouse.arrpoints["y"], canvas.points)
|
||||||
|
|
||||||
|
console.log("Checking Point " + point + " in path " + inPoints + " path length is " + canvas.path.length)
|
||||||
|
if (inPoints == true) {
|
||||||
|
var alreadyInPath = false
|
||||||
|
for(var i=0;i<canvas.path.length;i++) {
|
||||||
|
if (canvas.path[i] == point) {
|
||||||
|
console.log("Point already in path!!")
|
||||||
|
|
||||||
|
alreadyInPath = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alreadyInPath == false) {
|
||||||
|
canvas.path.push(point)
|
||||||
|
console.log("Pushing " + point + " to path" + canvas.path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
canvas.path = []
|
||||||
|
}
|
||||||
|
gameScore.text = Utils.scorePath(canvas.path)
|
||||||
|
canvas.requestPaint()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: gameScoreLabel
|
||||||
|
text: "Sequence Score: "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: gameScore
|
||||||
|
text: Utils.scorePath(canvas.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleButton { // New Game
|
||||||
|
id: btnSubmitSolution
|
||||||
|
icon: "regular/paper-plane"
|
||||||
|
text: "submit solution"
|
||||||
|
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
|
||||||
|
property int nextMessageID: 1
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (canvas.path.length == canvas.points.length) {
|
||||||
|
var msg = JSON.stringify({"o":3, "p":canvas.path, "s":canvas.points})
|
||||||
|
gcd.sendMessage(msg, nextMessageID++)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
43
qml/utils.js
43
qml/utils.js
|
@ -8,3 +8,46 @@ function htmlEscaped(str) {
|
||||||
str = str.replace(/'/g, "'");
|
str = str.replace(/'/g, "'");
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getRandomInt(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseToGrid(x,y) {
|
||||||
|
return {"x":Math.floor(x/40), "y":Math.floor(y/40)}
|
||||||
|
}
|
||||||
|
|
||||||
|
function distance(a,b) {
|
||||||
|
let ax = Math.floor(a/16)
|
||||||
|
let ay = a%16
|
||||||
|
|
||||||
|
let bx = Math.floor(b/16)
|
||||||
|
let by = b%16
|
||||||
|
|
||||||
|
return Math.abs(ax-bx) + Math.abs(ay-by)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function scorePath(path) {
|
||||||
|
var pathLength = 0
|
||||||
|
for (var i=0;i<path.length-1;i++) {
|
||||||
|
pathLength += distance(path[i],path[i+1])
|
||||||
|
console.log("Path Length:" + pathLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ""+pathLength
|
||||||
|
}
|
||||||
|
|
||||||
|
function isGridOccupied(x, y, points) {
|
||||||
|
var inPoints = false
|
||||||
|
for (var i=0;i<points.length;i++) {
|
||||||
|
if (((x*16)+y) == points[i]) {
|
||||||
|
inPoints = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inPoints
|
||||||
|
}
|
Loading…
Reference in New Issue