mirror of
https://github.com/danbee/scoreboard
synced 2025-03-04 08:59:11 +00:00
Add serve tracking
This commit is contained in:
parent
4f1b874c3f
commit
214d4c970f
@ -40,3 +40,6 @@ DEPENDENCIES
|
||||
pusher
|
||||
redis-objects
|
||||
sinatra
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.6
|
||||
|
||||
10
README.md
10
README.md
@ -1,5 +1,4 @@
|
||||
Table Tennis Score Board
|
||||
=======================
|
||||
# Table Tennis Score Board
|
||||
|
||||
Implements a table tennis scoreboard which can be updated by PUTing to
|
||||
particular URL's. This was part of a hack day project that involved buttons
|
||||
@ -13,8 +12,7 @@ The back end is Sinatra and the front end is powered by Riot.js. Redis is used
|
||||
for data persistence. Pusher is used for communication between the back end and
|
||||
the front.
|
||||
|
||||
Instructions
|
||||
------------
|
||||
## Instructions
|
||||
|
||||
Install the bundle:
|
||||
|
||||
@ -27,3 +25,7 @@ Run the server:
|
||||
```sh
|
||||
$ bundle exec foreman start
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
Ping Pong Paddle icon by Anbileru Adaleru from the Noun Project
|
||||
|
||||
53
lib/match.rb
53
lib/match.rb
@ -1,4 +1,9 @@
|
||||
class Match
|
||||
include Redis::Objects
|
||||
|
||||
value :initial_serve
|
||||
value :serve
|
||||
|
||||
def initialize(name_one = nil, name_two = nil)
|
||||
@one, @two = Player.new(:one),
|
||||
Player.new(:two)
|
||||
@ -10,16 +15,48 @@ class Match
|
||||
players[colour].score.increment
|
||||
if @one.has_beaten(@two)
|
||||
reset_scores
|
||||
swap_initial_serve
|
||||
@one.games.increment
|
||||
elsif @two.has_beaten(@one)
|
||||
reset_scores
|
||||
swap_initial_serve
|
||||
@two.games.increment
|
||||
end
|
||||
set_serve
|
||||
end
|
||||
|
||||
def set_serve
|
||||
total_points = @one.score.value + @two.score.value
|
||||
initial_server = (total_points / 2).even?
|
||||
case self.initial_serve.value
|
||||
when 'blue'
|
||||
self.serve = initial_server ? :blue : :red
|
||||
when 'red'
|
||||
self.serve = initial_server ? :red : :blue
|
||||
end
|
||||
end
|
||||
|
||||
def swap_initial_serve
|
||||
case self.initial_serve.value
|
||||
when 'red'
|
||||
set_initial_serve(:blue)
|
||||
when 'blue'
|
||||
set_initial_serve(:red)
|
||||
end
|
||||
end
|
||||
|
||||
def undo_point(colour)
|
||||
player = players[colour]
|
||||
player.score.decrement if player.score.value > 0
|
||||
if player.score.value > 0
|
||||
player.score.decrement
|
||||
elsif no_scores?
|
||||
set_initial_serve(colour)
|
||||
end
|
||||
end
|
||||
|
||||
def set_initial_serve(colour)
|
||||
self.initial_serve = colour
|
||||
self.serve = colour
|
||||
end
|
||||
|
||||
def reset_scores
|
||||
@ -30,6 +67,7 @@ class Match
|
||||
def reset_games
|
||||
@one.games.reset
|
||||
@two.games.reset
|
||||
set_initial_serve(nil)
|
||||
end
|
||||
|
||||
def total_games
|
||||
@ -45,7 +83,16 @@ class Match
|
||||
end
|
||||
|
||||
def scores
|
||||
{ red: players[:red].attributes,
|
||||
blue: players[:blue].attributes }
|
||||
{ red: players[:red].attributes.merge(serve: self.serve == 'red'),
|
||||
blue: players[:blue].attributes.merge(serve: self.serve == 'blue') }
|
||||
end
|
||||
|
||||
def no_scores?
|
||||
@one.score == 0 && @two.score == 0
|
||||
end
|
||||
|
||||
# This is required for Redis
|
||||
def id
|
||||
1
|
||||
end
|
||||
end
|
||||
|
||||
12
public/images/bat.svg
Normal file
12
public/images/bat.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="90px" height="92px" viewBox="0 0 90 92" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: Sketch 3.4.3 (16618) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Untitled</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="Group" sketch:type="MSLayerGroup" transform="translate(0.000000, 0.637840)" fill="#FFFFFF">
|
||||
<path d="M8.967063,9.80389 C5.453263,13.37779 2.7147229,17.66639 1.3376029,22.01479 C-0.6553471,28.30849 -0.4154371,35.52099 2.0184029,42.47089 C3.5436129,46.8259 5.026023,49.6718 8.088573,54.123 C9.908033,56.7678 15.053022,61.9132 17.939312,63.9739 C25.198772,69.1585 30.279242,71.1426 36.191522,71.1017 C39.986692,71.0757 41.743242,70.5289 44.410382,69.7591 C46.700582,69.0982 49.031102,67.3719 50.996852,66.9747 C53.854932,66.3971 55.731872,66.7762 58.683552,68.5271 C62.925762,71.0437 68.404132,76.3297 75.008702,84.2798 C77.483042,87.2582 79.784212,89.8723 80.122802,90.0888 C80.461402,90.3056 81.055792,90.4165 81.443722,90.3358 C82.327362,90.1516 84.493652,88.5271 86.430582,86.793 L86.430922,86.7934 C88.164992,84.8563 89.789592,82.6901 89.973552,81.8064 C90.054452,81.4185 89.943352,80.8241 89.726782,80.4855 C89.510112,80.147 86.896082,77.8458 83.917712,75.3714 C75.967682,68.7666 70.681622,63.2883 68.165072,59.046 C66.414172,56.0945 66.035172,54.2174 66.612732,51.3594 C67.010022,49.3936 68.736202,47.063 69.397082,44.7728 C70.166772,42.10569 70.713532,40.34899 70.739792,36.55389 C70.780592,30.64169 68.796532,25.56099 63.611892,18.30149 C61.551142,15.41529 56.405882,10.27029 53.761142,8.45069 C49.309802,5.38819 46.464012,3.90569 42.109042,2.38069 C35.159092,-0.05331 27.946832,-0.29321 21.653132,1.69989 C17.304772,3.07689 13.015962,5.81539 9.442263,9.32919 L9.441913,9.32949 C9.362313,9.40749 9.284033,9.48799 9.205083,9.56709 L9.204743,9.56669 L8.967583,9.80389 L8.967063,9.80389 L8.967063,9.80389 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -36,6 +36,16 @@ body {
|
||||
top: 3rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
.scores div .serve {
|
||||
position: absolute;
|
||||
top: 9rem;
|
||||
}
|
||||
.scores div .serve img {
|
||||
display: none;
|
||||
}
|
||||
.scores div .serve img.show {
|
||||
display: block;
|
||||
}
|
||||
#red-score { background: #b00; }
|
||||
#blue-score { background: #00b; }
|
||||
#red-score .score { right: 5rem; }
|
||||
@ -44,6 +54,8 @@ body {
|
||||
#blue-score .games { right: 5rem; }
|
||||
#red-score .name { right: 5rem; }
|
||||
#blue-score .name { left: 5rem; }
|
||||
#red-score .serve { right: 5rem; }
|
||||
#blue-score .serve { left: 5rem; }
|
||||
|
||||
.controls {
|
||||
position: absolute;
|
||||
|
||||
@ -4,11 +4,13 @@
|
||||
<span class="name">{ players.blue.name }</span>
|
||||
<span class="score">{ players.blue.score }</span>
|
||||
<span class="games">{ players.blue.games }</span>
|
||||
<span class="serve"><img class={ show: players.blue.serve } src="/images/bat.svg" alt="service"></span>
|
||||
</div>
|
||||
<div id="red-score">
|
||||
<span class="name">{ players.red.name }</span>
|
||||
<span class="score">{ players.red.score }</span>
|
||||
<span class="games">{ players.red.games }</span>
|
||||
<span class="serve"><img class={ show: players.red.serve } src="/images/bat.svg" alt="service"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -73,5 +73,4 @@ class Scoreboard < Sinatra::Base
|
||||
def match
|
||||
@match ||= Match.new
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user