Code for a fitness function for bidding systems [Desiderius part #18]

Last week I wrote about my strategy for creating the fitness function data, and now, I have really written the code! So, here goes. We create a deck of cards and select 13 random ones.

//make a list with (all) 52 cards
 let theWholeDeck = cartesian allCardSuits allRanks
//get one random hand and the rest of the deck
 let (hand1, remainder1) = randomHandplusRemainder theWholeDeck

Randomness needed

For the randomHandplusRemainder function, I needed some code to randomly select 13 cards out of the 52. So, as you do, I googled and landed on StackOverflow, where I found this code:

let takeRandomFrom xs n = 
   let insertAt n xs x = Seq.concat [Seq.take n xs; seq [x]; Seq.skip n xs]
   let randomInsert xs = insertAt (rnd.Next( (Seq.length xs) + 1 )) xs
   xs |> Seq.fold randomInsert Seq.empty |> Seq.take n

In retrospect, should have been more sceptical as the answer had no upvotes 🙂 The code works, but it does not perform, at all* When I found out, I myself wrote a better version. While writing this I am thinking it would be nice to post this on SO too. Will do that later.

let rec takeRandomFrom (xs: 'a List) n = //modified from generate random hands, should be moved to a general helper(TODO)
   match xs with
   | [] -> []
   | xs ->  match n with
            | 0 -> []
            | n -> let randomIndex = rnd.Next(xs.Length)
                   let randomItem = xs.[randomIndex]

                   let rest1 = takeFromList randomIndex xs
                   let rest2 = skipFromList (randomIndex+1) xs  

                   randomItem :: takeRandomFrom (List.append rest1 rest2) (n-1)

Way quicker!

* which I only found out at a later stage of the project thought!


1 Comment

  1. Akash Chopra

    Great series, thanks for posting these articles!

    Minor point: I’m not sure if assuming that your partner has zero points will lead to a sensible bid for your hand. Many (most?) reasonable, minimum opening hands, opposite a partner who has no points, will fail to make any contract. I suspect that it is better to assume that the remaining points are distributed randomly among the other three players.

Comments are closed.