Mike Kemner
MAT 385
5/1/2013
Daisy Petal Problem
The problem under examination is how to ensure victory on the game “Daisy Petals” with a
strategy that cannot be beat if you are the second player to move. The game can be found at By being the second playerto move you can ensure the ultimate outcome of the game. The object of the game is to bethe last one to pull the flower petal or petals off of the daisy. Valid moves include removingone petal or two petals that are right next to each other. The clever second player can makesome observations and employ a tactic that the computer will never be able to overcome.I encourage everyone to play the game before reading further. Try to come up with your ownstrategy that will defeat the computer. There may be more than one! One hint before you start,force the game into an even number of turns for you. Since you are the second player and the numberof petals on the flower is even you would ensure victory.
The following proof sequence will prove that any number of 4's summed together with an number of 2's is an even number. This is relevant because part of the requirement to winning the game is that you as the second player must ensure that you are the last person to remove petals from the flower. Countering the computer by mimicking the number of petals it removes ensures that the last move will end on an even turn for you. If the computer removes one petal you must also remove one petal (1+1 = 2). If the computer removes two petals you must also remove two petals (2+2 = 4). So, the sum of any combination of 2's and 4's is even. Since you are the second person and the number of turns you have played is even you have guaranteed a victory.
First prove 4m is even.
Definition: 2n is even
Claim: 4m is even.
x = 4m
= 2(2m) = 2(n) ✓∴ 4m is even!
Now prove the sum of two even numbers is even.
Claim: x + y is even where x and y are even integers.
Definition: 2n is even. Also, ∃ integers m1 and m2∋ x = 2m1 and y = 2m2
∴ x + y = 2m1 + 2m2
= 2(m1+m2)
=2(n)✓
∴x + y is an even number!
Did you come up with a winning strategy? You may have found it hard to force the game into an
even number of moves because the computer came up with a situation that prevented your next
even move from happening. The next key observation is that you must keep the flower symmetrical
in order to force the opponent from dictating the outcome of the game. If you reflect the move
of the opponent to the opposite side of the flower and match the number of petals the computer
removes you have effectively guaranteed an even number of moves. An example of symmetrical move can be seen below. If the computer chose to remove the petal located at 12 o'clock then to ensure victory the strategy dictates that you must counter by removing the petal at 6 o'clock. The two figures below show an untouched flower then the flower after the next two moves have taken place. The moves show the computer taking the first move at 12 o'clock and the user makes a counter move at 6 o'clock.
The same approach must be taken if two petals are being removed by the computer. You must reflect the same move on the opposite side of the circle. Below shows the computer removing petals from 12 o'clock and 10 o'clock and the user countering with a reflecting move at 6 o'clock and a 4 o'clock.
Petal solving program. The code below is for the accompanying Flower Solving program. The c# program will execute the algorithm described above to solve the 20 petal flower problem. Simply give the program the last move from the computer and the program will tell you where to advance next.
Code for the accompanying Petal Solver Program:
/* Mike Kemner
* 5/1/2013
* MAT385
* Program solves the puzzle of which moves to make against the computer in
* a flash game located at: The program
* will guarantee a win against the computer provided that you are the second
* person to make a move. With the correct strategy it is impossible to lose
* if you are the second person to start.
*/
using System;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
using System.Drawing.Drawing2D;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
publicpartialclassForm1 : Form {
constint TOTAL_PETALS = 20;
public Form1() {
InitializeComponent();
txtPetal2.ReadOnly = true;
}
/* Method is button click event and logic for determining which
* petal(s) to remove from the board
*/
privatevoidbtnGenerate_Click(object sender, EventArgs e) {
int petal1 = 0;
int petal2 = 0;
intpetalToRemove = 0;
pictureBox1.Refresh();
lblStatus.Text = "";
//case two numbers were entered
if ( txtPetal1.Text != "" & txtPetal2.Text != "" ) {
try {
//retreive form data
petal1 = int.Parse(txtPetal1.Text);
petal2 = int.Parse(txtPetal2.Text);
//check if number is in range 1-20 and adjacency
if ( isValidNumber(petal1, petal2) ) {
petalToRemove = reflectAnswer(petal1, petal2);
//removing two leafs, must cycle around the circle from 20 to 1
if (petalToRemove == TOTAL_PETALS) {
drawCircle(petalToRemove);
drawCircle(1);
} else { //nomral case
drawCircle(petalToRemove);
drawCircle(petalToRemove + 1);
}
} else { //one or both of the numbers wasn't in range or adjacent
lblStatus.Text = "Enter numbers adjacent to each other \nand in range of 1-20";
}
} catch (FormatException) { //wasn't a number
lblStatus.Text = "Invalid Number Error, there!";
} catch (OverflowException) {
lblStatus.Text = "One of the Numbers you entered \nwas too large!";
}
}
//case only one field was entered
elseif (txtPetal1.Text != "") {
try {
//retreive form data
petal1 = int.Parse(txtPetal1.Text);
//check if number is in range 1-20
if (isValidNumber(petal1)) {
petalToRemove = reflectAnswer(petal1);
drawCircle(petalToRemove);
} else { //wasn't a valid number
lblStatus.Text = "Enter number in range of 1-20";
}
} catch (FormatException) {
lblStatus.Text = "Invalid Number Error, here!";
} catch (OverflowException) {
lblStatus.Text = "One of the Numbers you entered \nwas too large!";
}
}
txtPetal1.Focus();
}
/* Method detects when text is present in first textBox. If not text
* is present then the second textbox is not available.
*/
privatevoid txtPetal1_TextChanged(object sender, EventArgs e)
{
if (txtPetal1.Text == null || txtPetal1.Text == "") {
txtPetal2.Text = null;
txtPetal2.ReadOnly = true;
} else {
txtPetal2.ReadOnly = false;
}
}
/* Method checks if the number(s) are in range of 1-20 and also if the
* two petals are next to on another on the flower.
*/
privateboolisValidNumber(int petal1, int petal2) {
//check if both inputs are in range 1-20
if (petal1 <= TOTAL_PETALS & petal1 >= 1 & petal2 <= TOTAL_PETALS & petal2 >= 1) {
//check if both inputs are adjacent to each other
if (petal1 + 1 == petal2 || petal1 - 1 == petal2) {
returntrue;
}
}
returnfalse;
}
/* Method checks if the number is in range of 1-20 */
privateboolisValidNumber(int petal) {
//check if input is in range of 1-20
if (petal <= TOTAL_PETALS & petal >= 1) {
returntrue;
}
returnfalse;
}
/* Method reflects the first petal answer back around the circle of 20 */
privateintreflectAnswer(int petal1, int petal2) {
//return the smallest of the two reflections
if (petal1 < petal2) {
returnreflectAnswer(petal1);
} else {
returnreflectAnswer(petal2);
}
}
/* Method reflects the answer back around the circle of 20 */
privateintreflectAnswer(int petal) {
constint REFLECT = 10;
//return the reflection
if (petal <= REFLECT) {
return petal + REFLECT;
} else {
return petal - REFLECT;
}
}
/* Method draws a circle around the target of the number(s) to choose */
privatevoiddrawCircle(int index) {
Graphics dc = pictureBox1.CreateGraphics();
PenredPen = newPen(Color.Red, 5);
//number to circle
switch (index) {
case 1:
dc.DrawEllipse(redPen, 219, 0, 40, 40);
break;
case 2:
dc.DrawEllipse(redPen, 270, 8, 40, 40);
break;
case 3:
dc.DrawEllipse(redPen, 315, 34, 40, 40);
break;
case 4:
dc.DrawEllipse(redPen, 353, 60, 40, 40);
break;
case 5:
dc.DrawEllipse(redPen, 378, 103, 40, 40);
break;
case 6:
dc.DrawEllipse(redPen, 390, 160, 40, 40);
break;
case 7:
dc.DrawEllipse(redPen, 378, 200, 40, 40);
break;
case 8:
dc.DrawEllipse(redPen, 347, 262, 40, 40);
break;
case 9:
dc.DrawEllipse(redPen, 310, 293, 40, 40);
break;
case 10:
dc.DrawEllipse(redPen, 274, 312, 40, 40);
break;
case 11:
dc.DrawEllipse(redPen, 210, 319, 40, 40);
break;
case 12:
dc.DrawEllipse(redPen, 168, 309, 40, 40);
break;
case 13:
dc.DrawEllipse(redPen, 127, 294, 40, 40);
break;
case 14:
dc.DrawEllipse(redPen, 78, 250, 40, 40);
break;
case 15:
dc.DrawEllipse(redPen, 55, 205, 40, 40);
break;
case 16:
dc.DrawEllipse(redPen, 50, 157, 40, 40);
break;
case 17:
dc.DrawEllipse(redPen, 66, 107, 40, 40);
break;
case 18:
dc.DrawEllipse(redPen, 94, 60, 40, 40);
break;
case 19:
dc.DrawEllipse(redPen, 122, 27, 40, 40);
break;
case 20:
dc.DrawEllipse(redPen, 174, 8, 40, 40);
break;
}
}
}
}