Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UX #4

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

UX #4

wants to merge 9 commits into from

Conversation

willcurry
Copy link
Owner

No description provided.

Copy link

@sarahabimay sarahabimay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Biggest things are the missing tests for new functionality in board.clj and the missing validation.

(defn make-move-computer [board player]
(mark-board board (find-best-move board player) player))

(defn play-until-over [board gamemode]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the tests for this new functionality?

(defn- clear-console []
(println "\033[H\033[2J"))

(defn- welcome-user []

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no spec for this

(defn show-gamemode-options []
(clear-console)
(welcome-user)
(println "\033[36mType 0 to play human vs human. \n1 to play vs a computer. \n2 to watch two computers play."))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not clear when displayed in the console. Probably because of the word 'type' being either a verb or a noun.. You could lose 'type' altogether and have:
0 - to play human vs human
1 - to play ....

(cond
(= input 1) (play-until-over board :hvc)
(= input 2) (play-until-over board :cvc)
:else (play-until-over board :hvh))))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about invalid entries? Where should the responsibility for validation go?

(it "should know valid positions"
(should= false (valid-position? ["x"] 0)))
(it "should know if a position is valid"
(should= true (valid-position? ["x" "-"] 1)))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use the function should and should-not rather than should= when things are just true/false


(it "displays the board correctly"
(should-contain "x--\nx--\n---"
(with-out-str (show-board ["x" "-" "-" "x" "-" "-" "-" "-" "-"]))))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use keywords to represent marks, rather than strings.
Strings have individual areas of memory, whereas keywords share areas, like constants. I.e. "x" "x" takes up 2 unit of memory, whereas :x :x takes up just 1 unit.


(defn game-over? [board]
(or (draw? board) (any-wins? board)))

(defn- read-move []
(read-string (read-line)))

(defn make-move [board]
(defn make-move [board player]
(let [move (read-move)]
(cond
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an if statement I think?

(recur (make-move board))))
(let [turn (find-turn board)]
(cond
(and (= gamemode :hvc) (= turn "o")) (recur (make-move-computer board turn) gamemode)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

game-mode

(println "\033[36mType 0 to play human vs human. \n1 to play vs a computer. \n2 to watch two computers play."))

(defn show-board [board]
(let [partitioned-board (map #(apply str %) (partition 3 board))]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 3 here is breaking encapsulation. Create a board-size function in your board namespace and call that instead. Your display functions should not know the size of the board.

(defn show-round-message [board]
(println (str "\033[35m" "--------------------------"))
(cond
(any-wins? board) (println (str (last-move board) " has won the game!"))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These println calls can be dragged outside the cond

@@ -1,22 +1,45 @@
(ns clojure-ttt.game
(use [clojure-ttt.board]))
(use [clojure-ttt.board]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use use. Prefer (refer [clojure-ttt.board] :as board)

@@ -29,8 +29,11 @@
(it "should know if there is a draw"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You use the words should know a lot, I would either simplify that to knows or determines
e.g. (it 'determines if a position is valid')

@dirv
Copy link

dirv commented Apr 12, 2017

While the overall Clojure code is clean, you still need to work on TDD. It's very noticeable when tests are written after (or not at all). E.g. board/find-turn, you have one test. But the function is an if statement, so there are two outcomes depending on input, meaning you need (at least two tests). Otherwise I can make your test pass with much simpler code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants