From 8590b917d9503d48e3d75ea0ee32c361e86a3297 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 06:40:25 +0000
Subject: [PATCH 1/4] feat: add AI opponent placeholder and AI_PROMPT.md
- Add AI_PROMPT.md with backgammon board/dice prompt template for AI move suggestions
- Add .ai-icon dual-icon CSS (SmartToy + AutoAwesome) similar to .offline-icon
- Add disabled AI opponent 'coming soon' row in Friends list
- Add aiOpponent and aiComingSoon i18n keys
Agent-Logs-Url: https://github.com/ProLoser/PeaceInTheMiddleEast/sessions/1b9fb0a3-7909-475f-84d4-aac0ffad0d62
Co-authored-by: ProLoser <67395+ProLoser@users.noreply.github.com>
---
AI_PROMPT.md | 74 ++++++++++++++++++++++++++++++
public/locales/en/translation.json | 4 +-
src/Dialogues/Friends.css | 5 ++
src/Dialogues/Friends.tsx | 12 +++++
src/index.css | 25 ++++++++++
5 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 AI_PROMPT.md
diff --git a/AI_PROMPT.md b/AI_PROMPT.md
new file mode 100644
index 0000000..a937965
--- /dev/null
+++ b/AI_PROMPT.md
@@ -0,0 +1,74 @@
+# Backgammon AI Move Prompt
+
+Use this prompt template to ask an AI model for a valid backgammon move suggestion given a board state and dice roll.
+
+---
+
+## Prompt Template
+
+```
+We are playing backgammon. You are playing as {{color}} ({{color}} moves in the {{direction}} direction, from point {{start}} toward point {{end}} and then bearing off).
+
+### Board Configuration
+
+The board has 24 points numbered 1–24. Positive values represent {{positiveColor}} pieces; negative values represent {{negativeColor}} pieces. Zero means the point is empty.
+
+Board (point 1 to 24):
+{{board}}
+
+Pieces in prison (hit and waiting to re-enter):
+- White: {{prison.white}}
+- Black: {{prison.black}}
+
+Pieces already borne off (home):
+- White: {{home.white}}
+- Black: {{home.black}}
+
+### Dice
+
+You rolled: {{dice[0]}} and {{dice[1]}}
+{{#doubles}}(Doubles! You have four moves of {{dice[0]}} to use.){{/doubles}}
+
+### Your Task
+
+List every legal move you can make this turn using the dice above. For each move, specify:
+- The source point (or "prison" if re-entering from the bar)
+- The destination point (or "off" if bearing off)
+- Which die value is consumed
+
+If no legal moves are available, say "No moves possible – pass turn."
+
+### Rules to Enforce
+
+1. A player **must** use both dice if legally possible; if only one can be used, they must use the higher-value die if possible.
+2. A piece in **prison** must re-enter before any other move can be made. Re-entry is onto the opponent's home board (points {{entryRange}}) using the exact die value.
+3. A point occupied by **2 or more** opponent pieces is blocked – you cannot land on or pass through it.
+4. A point with exactly **1 opponent piece** (a blot) can be hit – the opponent's piece goes to prison.
+5. **Bearing off**: You may only bear off when all your pieces are in your home board (points {{homeRange}}). Use a die equal to the exact point, or the highest available die if no piece sits on that exact point, provided no pieces remain on higher points.
+6. Doubles give **4 moves** (not 2) of the shown value.
+
+Respond with a numbered list of moves, e.g.:
+1. Move from point 6 to point 2 (die: 4)
+2. Move from point 8 to point 6 (die: 2)
+```
+
+---
+
+## Field Reference
+
+| Placeholder | Source in `Game` type | Description |
+|---|---|---|
+| `{{color}}` | `game.color` | Current player's color (`white` or `black`) |
+| `{{board}}` | `game.board` (24-element array) | Piece counts per point; positive = white, negative = black |
+| `{{prison.white}}` | `game.prison.white` | White pieces on the bar |
+| `{{prison.black}}` | `game.prison.black` | Black pieces on the bar |
+| `{{home.white}}` | `game.home.white` | White pieces borne off |
+| `{{home.black}}` | `game.home.black` | Black pieces borne off |
+| `{{dice[0]}}`, `{{dice[1]}}` | `game.dice` | The two dice values rolled |
+
+### Direction by Color
+
+| Color | Moves toward | Entry range | Home board |
+|---|---|---|---|
+| White | Point 1 → 24, then off | Points 1–6 | Points 19–24 |
+| Black | Point 24 → 1, then off | Points 19–24 | Points 1–6 |
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 7fa61f5..2f681a2 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -27,5 +27,7 @@
"notificationsDisabled": "Notifications Disabled",
"notificationsEnabled": "Notifications Enabled",
"enableNotifications": "Enable Notifications",
- "privacyPolicy": "Privacy Policy"
+ "privacyPolicy": "Privacy Policy",
+ "aiOpponent": "AI Opponent",
+ "aiComingSoon": "Coming soon — pick your model"
}
diff --git a/src/Dialogues/Friends.css b/src/Dialogues/Friends.css
index 5f0164d..05cf606 100644
--- a/src/Dialogues/Friends.css
+++ b/src/Dialogues/Friends.css
@@ -71,6 +71,11 @@
overflow: hidden;
text-overflow: ellipsis;
}
+ &.ai-opponent {
+ opacity: 0.5;
+ cursor: not-allowed;
+ pointer-events: none;
+ }
> svg, > img {
width: 4em;
height: 4em;
diff --git a/src/Dialogues/Friends.tsx b/src/Dialogues/Friends.tsx
index 7174aee..425ff9d 100644
--- a/src/Dialogues/Friends.tsx
+++ b/src/Dialogues/Friends.tsx
@@ -22,6 +22,8 @@ import NotificationsOffIcon from '@material-design-icons/svg/filled/notification
import NotificationsActiveIcon from '@material-design-icons/svg/filled/notifications_active.svg?react';
import CircleNotificationsIcon from '@material-design-icons/svg/filled/circle_notifications.svg?react';
import LocalIcon from '@material-design-icons/svg/filled/location_on.svg?react';
+import SmartToyIcon from '@material-design-icons/svg/filled/smart_toy.svg?react';
+import AutoAwesomeIcon from '@material-design-icons/svg/filled/auto_awesome.svg?react';
import RestartAltIcon from '@material-design-icons/svg/filled/restart_alt.svg?react';
import BugReportIcon from '@material-design-icons/svg/filled/bug_report.svg?react';
import InfoIcon from '@material-design-icons/svg/filled/info.svg?react';
@@ -327,6 +329,16 @@ export default function Friends({ user, load, reset, friend }: FriendsProps) {
{t('local')}
: null}
+
+
+
+
+
+
+
{t('aiOpponent')}
+
+
+
{[...myTurnFriends, ...renderFriends]}
diff --git a/src/index.css b/src/index.css
index aa1b37f..c190b4e 100644
--- a/src/index.css
+++ b/src/index.css
@@ -91,6 +91,31 @@ body,
}
}
+.ai-icon {
+ position: relative;
+ display: inline-flex;
+ flex-shrink: 0;
+ width: 4em;
+ height: 4em;
+
+ > .material-icons-svg {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ fill: var(--primary);
+ }
+
+ > .material-icons-svg:last-child {
+ top: 30%;
+ left: 30%;
+ width: 55%;
+ height: 55%;
+ fill: white;
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
+ }
+}
+
.offline-icon {
position: relative;
display: inline-flex;
From 3f0728fad37e67376c7c9d525266e5948572cce5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 06:41:57 +0000
Subject: [PATCH 2/4] fix: correct board direction table in AI_PROMPT.md
Agent-Logs-Url: https://github.com/ProLoser/PeaceInTheMiddleEast/sessions/1b9fb0a3-7909-475f-84d4-aac0ffad0d62
Co-authored-by: ProLoser <67395+ProLoser@users.noreply.github.com>
---
AI_PROMPT.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/AI_PROMPT.md b/AI_PROMPT.md
index a937965..cdd0a55 100644
--- a/AI_PROMPT.md
+++ b/AI_PROMPT.md
@@ -70,5 +70,5 @@ Respond with a numbered list of moves, e.g.:
| Color | Moves toward | Entry range | Home board |
|---|---|---|---|
-| White | Point 1 → 24, then off | Points 1–6 | Points 19–24 |
-| Black | Point 24 → 1, then off | Points 19–24 | Points 1–6 |
+| White | Point 24 → 1, then off | Points 19–24 | Points 1–6 |
+| Black | Point 1 → 24, then off | Points 1–6 | Points 19–24 |
From d54a8ca741ed5c0b18888cc4207bccf36b0c83be Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 06:51:19 +0000
Subject: [PATCH 3/4] fix: require backgammon notation in AI prompt response
Agent-Logs-Url: https://github.com/ProLoser/PeaceInTheMiddleEast/sessions/e6b2919a-0c51-485b-a6dc-c83dd1aab22b
Co-authored-by: ProLoser <67395+ProLoser@users.noreply.github.com>
---
AI_PROMPT.md | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/AI_PROMPT.md b/AI_PROMPT.md
index cdd0a55..5102067 100644
--- a/AI_PROMPT.md
+++ b/AI_PROMPT.md
@@ -31,25 +31,28 @@ You rolled: {{dice[0]}} and {{dice[1]}}
### Your Task
-List every legal move you can make this turn using the dice above. For each move, specify:
-- The source point (or "prison" if re-entering from the bar)
-- The destination point (or "off" if bearing off)
-- Which die value is consumed
+Choose the best legal play for this turn and respond **only** in standard backgammon notation.
-If no legal moves are available, say "No moves possible – pass turn."
+**Notation rules:**
+- A single move: `source/destination` (e.g. `13/9`)
+- Multiple moves in one turn are space-separated: `13/9 6/2`
+- Re-entering from the bar: `bar/destination` (e.g. `bar/21`)
+- Bearing off: `source/off` (e.g. `3/off`)
+- When the same checker makes consecutive moves with both dice: `13/7/2`
+
+If no legal moves are available, respond with: `no move`
### Rules to Enforce
1. A player **must** use both dice if legally possible; if only one can be used, they must use the higher-value die if possible.
2. A piece in **prison** must re-enter before any other move can be made. Re-entry is onto the opponent's home board (points {{entryRange}}) using the exact die value.
-3. A point occupied by **2 or more** opponent pieces is blocked – you cannot land on or pass through it.
+3. A point occupied by **2 or more** opponent pieces is blocked – you cannot land on it.
4. A point with exactly **1 opponent piece** (a blot) can be hit – the opponent's piece goes to prison.
5. **Bearing off**: You may only bear off when all your pieces are in your home board (points {{homeRange}}). Use a die equal to the exact point, or the highest available die if no piece sits on that exact point, provided no pieces remain on higher points.
6. Doubles give **4 moves** (not 2) of the shown value.
-Respond with a numbered list of moves, e.g.:
-1. Move from point 6 to point 2 (die: 4)
-2. Move from point 8 to point 6 (die: 2)
+Example response for a roll of 4-2:
+`13/9 6/4`
```
---
From de63a4a06abfcc465cc7e5faf23c2af0f344f122 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 06:55:40 +0000
Subject: [PATCH 4/4] fix: remove verbose notation/rules from AI prompt (AI
knows backgammon)
Agent-Logs-Url: https://github.com/ProLoser/PeaceInTheMiddleEast/sessions/8f952fba-e34a-4aa2-bf0d-898e7634886a
Co-authored-by: ProLoser <67395+ProLoser@users.noreply.github.com>
---
AI_PROMPT.md | 23 +----------------------
1 file changed, 1 insertion(+), 22 deletions(-)
diff --git a/AI_PROMPT.md b/AI_PROMPT.md
index 5102067..88fcfaa 100644
--- a/AI_PROMPT.md
+++ b/AI_PROMPT.md
@@ -31,28 +31,7 @@ You rolled: {{dice[0]}} and {{dice[1]}}
### Your Task
-Choose the best legal play for this turn and respond **only** in standard backgammon notation.
-
-**Notation rules:**
-- A single move: `source/destination` (e.g. `13/9`)
-- Multiple moves in one turn are space-separated: `13/9 6/2`
-- Re-entering from the bar: `bar/destination` (e.g. `bar/21`)
-- Bearing off: `source/off` (e.g. `3/off`)
-- When the same checker makes consecutive moves with both dice: `13/7/2`
-
-If no legal moves are available, respond with: `no move`
-
-### Rules to Enforce
-
-1. A player **must** use both dice if legally possible; if only one can be used, they must use the higher-value die if possible.
-2. A piece in **prison** must re-enter before any other move can be made. Re-entry is onto the opponent's home board (points {{entryRange}}) using the exact die value.
-3. A point occupied by **2 or more** opponent pieces is blocked – you cannot land on it.
-4. A point with exactly **1 opponent piece** (a blot) can be hit – the opponent's piece goes to prison.
-5. **Bearing off**: You may only bear off when all your pieces are in your home board (points {{homeRange}}). Use a die equal to the exact point, or the highest available die if no piece sits on that exact point, provided no pieces remain on higher points.
-6. Doubles give **4 moves** (not 2) of the shown value.
-
-Example response for a roll of 4-2:
-`13/9 6/4`
+Choose the best legal play for this turn and respond **only** in standard backgammon notation. If no legal moves are available, respond with: `no move`
```
---