Hickymcmicky
Hickymcmicky

Reputation: 21

Functions to create a simplified darts game with randomized numbers and a win condition

I managed to create a pair of numbers with code

(defn dart-throwing [] 
   [(- (* 2 (rand-int 2)) 1) (- (* 2 (rand-int 2)) 1)])


(def onetrial (dart-throwing))

But I do not know how to create my win condition which would be x^2 + y^2 < 1

I tried writing

(defn won? [x y] 
  (< (+ (* x x) (* y y)) 1))

(won? onetrial)

I expected it to check the pair [] from dart-throwing and check if it was less than 1 giving a true or false

I would appreciate it if I had some help, thank you

Upvotes: 0

Views: 106

Answers (3)

leetwinski
leetwinski

Reputation: 17859

as far as i can see, you've got an incorrect throwing implementation, returning components -1 | 1 instead of -1 | 0 | 1.

what i would propose, is something like this:

(defn rand-axis [] (dec (rand-int 3)))

user> (repeatedly 10 rand-axis)
;;=> (-1 -1 0 -1 0 -1 -1 0 1 -1)

then you just use it in an attempt function:

(defn attempt [] [(rand-axis) (rand-axis)])

and the won? seems to be like the following:

(defn won? [[x y]] (zero? (+ (* x x) (* y y))))

check it:

user> (doseq [att (repeatedly 10 attempt)]
        (println (str "throw:\t" att "\twon?:\t" (won? att))))
;; throw:   [1 -1]  won?:   false
;; throw:   [-1 1]  won?:   false
;; throw:   [1 -1]  won?:   false
;; throw:   [0 1]   won?:   false
;; throw:   [1 1]   won?:   false
;; throw:   [-1 -1] won?:   false
;; throw:   [0 1]   won?:   false
;; throw:   [-1 1]  won?:   false
;; throw:   [0 0]   won?:   true
;; throw:   [-1 0]  won?:   false

moreover, since the only winning situation is [0 0], won? counld be like this:

(defn won? [pair] (= [0 0] pair))

or like this:

(defn won? [[a b]] (= 0 a b))

or even like this:

(def won? (comp boolean #{[0 0]}))

Upvotes: 0

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 9950

Your code does the same like:

(defn dart-throwing []
  [(rand-nth [-1 1])
   (rand-nth [-1 1])

(def onetrial (dart-throwing))

rand-nth chooses deliberately from the given collection - in this case -1 and 1.

And here is the problem: -1 squared is 1 - so (+ (* x x) (* y y)) will never be < than 1.

So: What is the point of the won? function?

Or shouldn't dart-throwing return some float between -1 and 1? a selection from the range? In this case rand-int is wrong. It must be then rand. so, instead of (- (* 2 (rand-int 2)) 1) it should be then (- (* 2 (rand)) 1). However, rand excludes the upper limit - in this case 1. One could send the upper limit to 1 + Float/MIN_VALUE to include 1. Or one keeps it but randomly choose between -1 and 1 and multiply them with the result - then one would get 1 included ... - but it wouldn't be a even distribution ...

Upvotes: 0

dpassen
dpassen

Reputation: 1306

Your won? function expects two arguments, an x and a y. Your onetrial is a vector of two elements, but it is a single argument here.

You have a couple of options:

You can use apply to 'spread' the vector into the argument list.

(apply won? onetrial)

OR

You can rewrite won? slightly using destructuring

(defn won? [[x y]] 
  (< (+ (* x x) (* y y)) 1))

Upvotes: 2

Related Questions