@chessceo/mcp 0.30.2 → 0.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // Pure mutation functions on a PrepFile tree. Each returns a new
2
- // PrepFile (structural sharing where safe) plus the effective path of
3
- // the touched node, so tools can report where the LLM's request
4
- // actually landed after any rebalancing.
2
+ // PrepFile (structural sharing where safe) plus the node_id of the
3
+ // touched node (the LLM addresses nodes by content-derived id — see
4
+ // paths.ts so tools return the id, not the path).
5
5
  //
6
6
  // All move-making mutations validate SAN against the current FEN via
7
7
  // chessops before touching the tree — a bad move surfaces as a thrown
@@ -11,15 +11,30 @@ import { parseFen } from "chessops/fen";
11
11
  import { Chess } from "chessops/chess";
12
12
  import { parseSan } from "chessops/san";
13
13
  import { makeFen } from "chessops/fen";
14
- import { cloneOnPath, getNode, PathError } from "./paths.js";
14
+ import { cloneOnPath, deriveNodeId, getNode, PathError } from "./paths.js";
15
15
  export class MutationError extends Error {
16
16
  }
17
- // Apply a SAN move as a new child at `path`. If the target already has
18
- // children, the new node is appended (becomes a variation, since
19
- // mainline is children[0]). Use promoteVariation to make the new node
20
- // the mainline afterwards if that's what you wanted.
21
- export function addMove(file, path, san) {
22
- const parent = getNode(file.root, path);
17
+ // Add a SAN move as a new child under `parentPath`. **Idempotent on
18
+ // SAN**: if a child with this SAN already exists under the parent, we
19
+ // return that existing child's id and leave the file unchanged. Same
20
+ // SAN from the same position IS the same move in chess — appending a
21
+ // duplicate sibling would (a) let the LLM create ambiguous "two lines
22
+ // both starting with d5" trees and (b) produce two nodes with the
23
+ // same content-derived id. Frontend's MoveService.playMove has the
24
+ // same "append new or navigate to existing" behaviour; this mirrors it.
25
+ //
26
+ // If there's no existing child with that SAN, we validate the move,
27
+ // derive the new id from (parent.id, san), and append. Because
28
+ // mainline is children[0], any appended move becomes a variation
29
+ // unless the parent had no children yet; use promoteVariation to
30
+ // switch mainline afterwards.
31
+ export function addMove(file, parentPath, san) {
32
+ const parent = getNode(file.root, parentPath);
33
+ // Idempotence: join to an existing child with the same SAN.
34
+ const existing = parent.children.find(c => c.san === san);
35
+ if (existing) {
36
+ return { file, id: existing.id };
37
+ }
23
38
  const move = validateSan(parent.fen, san);
24
39
  const posSetup = parseFen(parent.fen);
25
40
  if (posSetup.isErr)
@@ -30,19 +45,54 @@ export function addMove(file, path, san) {
30
45
  const board = pos.value;
31
46
  board.play(move);
32
47
  const childFen = makeFen(board.toSetup());
48
+ const newId = deriveNodeId(parent.id, san);
33
49
  const newNode = {
50
+ id: newId,
34
51
  san,
35
52
  fen: childFen,
36
53
  ply: parent.ply + 1,
37
54
  children: [],
38
55
  };
39
- const { root: newRoot, target } = cloneOnPath(file.root, path);
56
+ const { root: newRoot, target } = cloneOnPath(file.root, parentPath);
40
57
  target.children = [...target.children, newNode];
41
58
  return {
42
59
  file: { tags: file.tags, root: newRoot },
43
- path: [...path, target.children.length - 1],
60
+ id: newId,
44
61
  };
45
62
  }
63
+ // Add a linear sequence of moves under `parentPath` — one call for a
64
+ // whole variation instead of N add_move calls. Inherits addMove's
65
+ // idempotence: if the line's prefix overlaps an existing branch, we
66
+ // join to it and only start creating new nodes at the divergence
67
+ // point. So two `add_line` calls sharing a prefix (e.g. `[d5, Bb5,
68
+ // Nd7]` and `[d5, Bb5, Ne4]`) build a proper Y-shape — one d5 → one
69
+ // Bb5 → two siblings from there — not two duplicate chains.
70
+ //
71
+ // Returns the ids and SANs of every node along the resulting line
72
+ // (both joined and newly-created), so the LLM can address any of
73
+ // them next.
74
+ export function addLine(file, parentPath, sans) {
75
+ if (sans.length === 0)
76
+ throw new MutationError("add_line requires at least one san");
77
+ let cur = file;
78
+ let curPath = parentPath;
79
+ const line = [];
80
+ for (const san of sans) {
81
+ const step = addMove(cur, curPath, san);
82
+ cur = step.file;
83
+ // Find the child we just addressed (whether we appended a new
84
+ // node or joined to an existing one) by its id, so the next
85
+ // iteration extends from the RIGHT node — not necessarily the
86
+ // parent's last child.
87
+ const parent = getNode(cur.root, curPath);
88
+ const childIdx = parent.children.findIndex(c => c.id === step.id);
89
+ if (childIdx < 0)
90
+ throw new MutationError(`internal: node ${step.id} not found after addMove`);
91
+ curPath = [...curPath, childIdx];
92
+ line.push({ id: step.id, san });
93
+ }
94
+ return { file: cur, line };
95
+ }
46
96
  // Replace the comment on the node at `path`. Passing empty string /
47
97
  // null clears it.
48
98
  export function setComment(file, path, comment) {
@@ -52,7 +102,7 @@ export function setComment(file, path, comment) {
52
102
  target.comment = trimmed;
53
103
  else
54
104
  delete target.comment;
55
- return { file: { tags: file.tags, root: newRoot }, path };
105
+ return { file: { tags: file.tags, root: newRoot }, id: target.id };
56
106
  }
57
107
  // Replace the NAG list. Empty array clears.
58
108
  export function setNags(file, path, nags) {
@@ -64,7 +114,7 @@ export function setNags(file, path, nags) {
64
114
  target.nags = cleaned;
65
115
  else
66
116
  delete target.nags;
67
- return { file: { tags: file.tags, root: newRoot }, path };
117
+ return { file: { tags: file.tags, root: newRoot }, id: target.id };
68
118
  }
69
119
  // Replace visual annotations (arrows + highlighted squares). Empty
70
120
  // arrows and highlights arrays clear the annotations entirely.
@@ -75,11 +125,10 @@ export function setAnnotations(file, path, ann) {
75
125
  delete target.annotations;
76
126
  else
77
127
  target.annotations = { arrows: ann.arrows, highlights: ann.highlights };
78
- return { file: { tags: file.tags, root: newRoot }, path };
128
+ return { file: { tags: file.tags, root: newRoot }, id: target.id };
79
129
  }
80
130
  // Delete the node at `path` and all its descendants. Refuses to delete
81
- // the root. Returns the path of the deleted node's parent for the
82
- // caller's convenience.
131
+ // the root. Returns the id of the deleted node's parent.
83
132
  export function deleteSubtree(file, path) {
84
133
  if (path.length === 0)
85
134
  throw new MutationError("cannot delete root");
@@ -90,34 +139,38 @@ export function deleteSubtree(file, path) {
90
139
  throw new PathError(`delete index ${removeIdx} out of bounds`, path);
91
140
  }
92
141
  parent.children = parent.children.filter((_, i) => i !== removeIdx);
93
- return { file: { tags: file.tags, root: newRoot }, path: parentPath };
142
+ return { file: { tags: file.tags, root: newRoot }, id: parent.id };
94
143
  }
95
144
  // Promote the node at `path` to be its parent's first child (the
96
145
  // mainline). Silently no-ops if it's already the mainline. Refuses on
97
- // root (root has no parent to promote against).
146
+ // root (root has no parent to promote against). Returns the promoted
147
+ // node's id (unchanged by the reorder — IDs don't depend on sibling
148
+ // position).
98
149
  export function promoteVariation(file, path) {
99
150
  if (path.length === 0)
100
151
  throw new MutationError("cannot promote root");
101
152
  const parentPath = path.slice(0, -1);
102
153
  const idx = path[path.length - 1];
103
- if (idx === 0)
104
- return { file, path }; // already mainline
154
+ if (idx === 0) {
155
+ // Already mainline — return the existing id without touching anything.
156
+ const target = getNode(file.root, path);
157
+ return { file, id: target.id };
158
+ }
105
159
  const { root: newRoot, target: parent } = cloneOnPath(file.root, parentPath);
106
160
  const promoted = parent.children[idx];
107
161
  const rest = parent.children.filter((_, i) => i !== idx);
108
162
  parent.children = [promoted, ...rest];
109
- return { file: { tags: file.tags, root: newRoot }, path: [...parentPath, 0] };
163
+ return { file: { tags: file.tags, root: newRoot }, id: promoted.id };
110
164
  }
111
165
  // Replace the stored ceoEval on the node at `path`. Passing null clears.
112
- // This is what auto_evaluate calls per-node; also exposed as an op the
113
- // LLM can invoke directly if it wants to overwrite a stale eval.
166
+ // This is what auto_evaluate / cloud_analyse(node_id) calls per-node.
114
167
  export function setCeoEval(file, path, ev) {
115
168
  const { root: newRoot, target } = cloneOnPath(file.root, path);
116
169
  if (ev === null || (!ev.sf && !ev.lc0 && !ev.nag))
117
170
  delete target.ceoEval;
118
171
  else
119
172
  target.ceoEval = ev;
120
- return { file: { tags: file.tags, root: newRoot }, path };
173
+ return { file: { tags: file.tags, root: newRoot }, id: target.id };
121
174
  }
122
175
  // Set or clear a tag. Passing null / empty removes.
123
176
  export function setTag(file, key, value) {
@@ -144,7 +197,7 @@ function validateSan(fen, san) {
144
197
  const board = pos.value;
145
198
  const move = parseSan(board, san);
146
199
  if (!move) {
147
- throw new MutationError(`illegal SAN "${san}" at fen "${fen}". Call describe_position on this fen to see the full list of legal moves.`);
200
+ throw new MutationError(`illegal SAN "${san}" at fen "${fen}". Call describe_position on this node to see the full list of legal moves.`);
148
201
  }
149
202
  return move;
150
203
  }
@@ -163,4 +216,4 @@ export function pathOf(root, target) {
163
216
  return null;
164
217
  }
165
218
  // Re-exports so index.ts only imports from mutations.
166
- export { getNode, getParent } from "./paths.js";
219
+ export { getNode, getParent, buildIdIndex, resolveNodeId, NodeIdError, ROOT_ID } from "./paths.js";
@@ -11,6 +11,7 @@ import { parseSan } from "chessops/san";
11
11
  import { makeFen } from "chessops/fen";
12
12
  import { opposite } from "chessops/util";
13
13
  import { colorFromCode, } from "./types.js";
14
+ import { deriveNodeId, ROOT_ID } from "./paths.js";
14
15
  const CAL_RE = /\[%cal\s+([^\]]+)\]/g;
15
16
  const CSL_RE = /\[%csl\s+([^\]]+)\]/g;
16
17
  const CEO_EVAL_RE = /\[%ceo-eval\s+([^\]]+)\]/g;
@@ -105,7 +106,7 @@ export function parsePGN(pgn) {
105
106
  }
106
107
  const startPos = startResult.value;
107
108
  const rootFen = makeFen(startPos.toSetup());
108
- const root = { san: null, fen: rootFen, ply: 0, children: [] };
109
+ const root = { id: ROOT_ID, san: null, fen: rootFen, ply: 0, children: [] };
109
110
  // Root-level comment on the game (rare, but supported).
110
111
  const gameComments = game.moves.comments;
111
112
  if (gameComments && gameComments.length > 0) {
@@ -135,7 +136,13 @@ export function parsePGN(pgn) {
135
136
  pos.play(move);
136
137
  nodeFen = makeFen(pos.toSetup());
137
138
  }
138
- const node = { san, fen: nodeFen, ply, children: [] };
139
+ const node = {
140
+ id: deriveNodeId(treeParent.id, san),
141
+ san,
142
+ fen: nodeFen,
143
+ ply,
144
+ children: [],
145
+ };
139
146
  // Comment on this move (both "starting comments" attached to
140
147
  // variations and "after-move comments" — we fold both into the
141
148
  // node's own comment; the LLM doesn't need the PGN's positional
package/dist/pgn/paths.js CHANGED
@@ -1,7 +1,44 @@
1
- // Path-based addressing for the LLM. The frontend uses UUIDs but they
2
- // regenerate every parse, so we can't use them across sessions. Paths
3
- // are child-index arrays deterministic across parse/export cycles as
4
- // long as we don't reorder children on export.
1
+ // Node addressing for the LLM: stable content-derived IDs, resolved
2
+ // internally to array-of-child-indices `Path` for the mutation
3
+ // implementation. LLM-facing tools never accept a path they take a
4
+ // `node_id` (or `parent_id` for add_move) and this module turns it
5
+ // into the path the mutation code walks.
6
+ //
7
+ // The ID → path index is built once per parse and read many times per
8
+ // batch. Every mutation preserves IDs on unchanged nodes (IDs are pure
9
+ // functions of parent.id + san, so adding/removing/promoting siblings
10
+ // leaves every ID untouched), so callers don't need to rebuild the
11
+ // index between ops in a batch — they just extend it with the newly
12
+ // created node's id when applyMutations lands one.
13
+ import { createHash } from "node:crypto";
14
+ // Special ID for the root position (starting FEN, no move played).
15
+ export const ROOT_ID = "r";
16
+ // 8-hex-char (32-bit) content hash. Root is "r". Every other node's
17
+ // id is derived from (parent.id, san). Two children of the same parent
18
+ // with the same SAN are impossible in real chess — same SAN from the
19
+ // same position IS the same move — so within-parent same-id events
20
+ // mean the caller tried to duplicate a move that already exists;
21
+ // `addMove` handles that by joining to the existing child rather than
22
+ // appending a duplicate (see mutations.ts). Cross-tree birthday
23
+ // collisions in 32 bits at 1000 nodes are ~10^-4 — rare, and thrown
24
+ // at parse time rather than silently masked.
25
+ export function deriveNodeId(parentId, san) {
26
+ const h = createHash("sha256");
27
+ h.update(parentId);
28
+ h.update("|");
29
+ h.update(san);
30
+ return h.digest("hex").slice(0, 8);
31
+ }
32
+ // Bad-node-id errors so the LLM sees exactly what went wrong. Message
33
+ // carries the offending id, which is often a copy-paste bug (missing
34
+ // character, wrong file id, stale reference to a deleted node).
35
+ export class NodeIdError extends Error {
36
+ nodeId;
37
+ constructor(msg, nodeId) {
38
+ super(`${msg} (node_id=${nodeId})`);
39
+ this.nodeId = nodeId;
40
+ }
41
+ }
5
42
  export class PathError extends Error {
6
43
  path;
7
44
  constructor(msg, path) {
@@ -9,9 +46,40 @@ export class PathError extends Error {
9
46
  this.path = path;
10
47
  }
11
48
  }
49
+ // Build the id → path index for a whole tree. Also detects the rare
50
+ // collision (two nodes with the same 32-bit id) and throws so the
51
+ // caller can surface a clear message.
52
+ export function buildIdIndex(root) {
53
+ const index = new Map();
54
+ const walk = (node, path) => {
55
+ if (index.has(node.id)) {
56
+ throw new Error(`node id collision on "${node.id}" — two distinct nodes in the tree ` +
57
+ `hash to the same 32-bit id. This is statistically rare (~10^-4 at ` +
58
+ `1000 nodes); if you see this, please report the file so we can ` +
59
+ `widen the hash.`);
60
+ }
61
+ index.set(node.id, path);
62
+ for (let i = 0; i < node.children.length; i++) {
63
+ walk(node.children[i], [...path, i]);
64
+ }
65
+ };
66
+ walk(root, []);
67
+ return index;
68
+ }
69
+ // Resolve a node_id to a Path against a specific tree. Throws
70
+ // NodeIdError with a message the LLM can act on.
71
+ export function resolveNodeId(index, nodeId) {
72
+ const path = index.get(nodeId);
73
+ if (!path) {
74
+ throw new NodeIdError(`no node with this id in the tree. Either it was deleted since your ` +
75
+ `last read, you have a typo, or you're addressing a different file — ` +
76
+ `call read_prep_file to refresh`, nodeId);
77
+ }
78
+ return path;
79
+ }
12
80
  // Resolve a path to a node reference. Throws PathError if the path
13
- // escapes the tree — that's ALWAYS the LLM's fault, and the message
14
- // tells it exactly where things fell apart.
81
+ // escapes the tree — used internally by the mutation code after
82
+ // node_id path resolution.
15
83
  export function getNode(root, path) {
16
84
  let cur = root;
17
85
  for (let i = 0; i < path.length; i++) {
@@ -33,10 +101,9 @@ export function getParent(root, path) {
33
101
  const index = path[path.length - 1];
34
102
  return { parent, index };
35
103
  }
36
- // Read-only shallow clone helper the mutation functions use to avoid
37
- // hidden aliasing. Deep-clones nodes on the path from root to the
38
- // mutation target, leaving unrelated subtrees shared (they're
39
- // immutable-by-convention downstream, so this is safe and cheap).
104
+ // Deep-clone nodes on the path from root to the mutation target,
105
+ // leaving unrelated subtrees shared. Downstream code treats siblings
106
+ // as immutable so this sharing is safe.
40
107
  export function cloneOnPath(root, path) {
41
108
  const newRoot = { ...root, children: [...root.children] };
42
109
  const parentChain = [newRoot];
package/dist/pgn/types.js CHANGED
@@ -1,10 +1,21 @@
1
- // Compact tree types the LLM works with. No stable ids — chessops
2
- // regenerates them per parse — so we address nodes by PATH: the array
3
- // of child indices from the root. [] is the root, [0] is root's first
4
- // child, [0, 1] is the second child of the first child, etc.
1
+ // Compact tree types the LLM works with.
5
2
  //
6
- // Paths ARE stable across parse/export/reparse cycles because move
7
- // order is deterministic and we don't rearrange children on export.
3
+ // Nodes are addressed by a stable, content-derived `id`:
4
+ // root.id = "r"
5
+ // node.id = first 8 hex chars of sha256(parent.id + "|" + san)
6
+ //
7
+ // The derivation is a pure function of the tree structure, so IDs
8
+ // survive parse → mutate → export → reparse without needing to be
9
+ // persisted in the PGN. Sibling insertions, deletions and variation
10
+ // promotions all leave every other node's ID unchanged — the failure
11
+ // mode of path-based addressing (later paths shifting when an earlier
12
+ // op inserts a sibling) simply cannot happen. See src/pgn/paths.ts
13
+ // for the id → path resolution used to power mutation calls.
14
+ //
15
+ // 32-bit width (8 hex chars) means birthday-collision probability
16
+ // is ~10^-4 even at 1000 nodes — the largest prep files we see are
17
+ // well under that. On the rare parse-time collision we throw a clear
18
+ // error rather than persisting anything ambiguous.
8
19
  // Named colours as they appear in the parsed tree. The wire format uses
9
20
  // single-letter codes (G, R, Y, C, B, O); the tree uses these longer
10
21
  // names to match how the frontend represents them.
@@ -6,6 +6,16 @@ When you call `cloud_analyse`, chess.ceo runs Stockfish and Lc0 in parallel on t
6
6
 
7
7
  **Every claim you make about a position must trace back to actual engine output from this session.** Not from a book you were trained on, not from generic chess principles, not from a plausible-sounding pattern. If you don't have a Stockfish or Lc0 line for the exact FEN you're discussing, run one. Compute is cheap — `cloud_analyse` at ~2s each is fine to call 5-10 times while walking a tree; you can burn 20-30 seconds of billable time and it's still cents.
8
8
 
9
+ ### The node-id + quote_engine_eval protocol
10
+
11
+ **When you're inside a prep file, call `cloud_analyse` with `file_id`+`node_id` — never with a hand-typed FEN.** The server derives the FEN from the tree node and, critically, **auto-stores the resulting eval on that node's `ceoEval`**. This is what makes engine attribution trustworthy end-to-end:
12
+
13
+ 1. `cloud_analyse({ id, node_id })` — runs analysis on the node's exact position, stores `{sf, lc0, nag}` on the node.
14
+ 2. Later, before you write "engines say X on this position" in a comment, call `quote_engine_eval({ id, node_id })` — it returns the stored eval or `null`.
15
+ 3. If `quote_engine_eval` returns `null`, you have no measurement to cite. **Do NOT infer an eval for a node from siblings, from children, or from a "position that looks similar."** Either analyse the node (`cloud_analyse`) or omit the number from your prose entirely.
16
+
17
+ Concrete failure this rule blocks: the LLM says *"9...Bb7: both engines 0.00"* after only calling `cloud_analyse` on the child positions (post-1.d4, post-castling). Both continuations really returned 0.00, but the Bb7 node was never analysed, and the claim reads to the user as a measurement. With this protocol, `quote_engine_eval(node_id=Bb7)` would return null and the LLM would either analyse it or reword to *"both continuations run to 0.00, so this position looks balanced"* (soft inference, honestly labelled).
18
+
9
19
  **Concrete failure modes to avoid:**
10
20
 
11
21
  - Inventing an evaluation. If you say "this is +0.4 for White", that number must come from an engine call. Not a guess, not a vibe.
@@ -0,0 +1,12 @@
1
+ [Event "1600+"]
2
+ [Site "?"]
3
+ [Date "2026.05.11"]
4
+ [Round "?"]
5
+ [White "Overview: Italian Fried Liver"]
6
+ [Black "?"]
7
+ [Result "*"]
8
+ [ECO "C57"]
9
+ [Opening "Italian Game"]
10
+ [Annotator "Chess.ceo"]
11
+
12
+ 1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 {[%csl Rf7]} d5 (4... Bc5 $6 {The Traxler variation} 5. Bxf7+ {Seen as the modern refutation.} (5. Nxf7 {Most principled. Interesting is that not long ago computers were saying this is winning for white. But modern strong engines almost immediately proclaim 0,00} Bxf2+ 6. Kf1 (6. Kxf2 {This usually leads to a draw} Nxe4+ 7. Kg1 (7. Ke3 Qh4 8. g3 Nxg3 9. hxg3 Qd4+ 10. Kf3 O-O) 7... Qh4 8. g3 Nxg3 9. Nxh8 Nd4 10. hxg3 Qxg3+ 11. Kf1 Qf4+ $10) 6... Qe7 7. Nxh8 d5 8. exd5 Nd4 9. d6 $1 (9. c3 {Most played, and weak engines still like this move, but fail to spot} Bg4 10. Qa4+ Nd7 $1 {And black is winning} 11. Kxf2 Qh4+) 9... Qxd6 (9... cxd6 $2 10. Kxf2 Ng4+ 11. Kg1 $18 {and the d6 pawn blocks Qc5}) 10. Nf7 {and here both} Qe7 {and} (10... Qc5 {are okay for black with plenty left to analyze})) (5. Nxh7) 5... Ke7 {Now white has 3 squares to return to.} 6. Bc4 $1 {By far the least played, but clearly the best, now white can always counter Bg4 with Be2. [%cal Gc4e2]} (6. Bd5 {The most played move. Back in the day this was known as the way to refute the Traxler, and played by Karpov against Beliavsky.} Rf8 7. O-O d6 $13 {Also the computer admits that black has compensation here, with Qe8-Qg6 and Bg4 coming.} 8. h3 Qe8 9. c3 Qg6 10. d4 Bb6 $13) (6. Bb3 {A good move, but white has to remain accurate} d6 7. d3 (7. Nf7 Qf8 8. Nxh8 $4 Bxf2+ $19) (7. O-O $2 Bg4) 7... Qe8 8. c3 Rf8 9. Nf3 Qg6 10. O-O Bg4 11. Nbd2 $16 {Although objectively black has no compensation for the pawn, it does seem black still has some practical chances.} Kd8 12. Kh1 Qh5 13. Qe2 Ne7) 6... Rf8 7. Nc3 Qe8 8. O-O h6 9. Nf3 d6 10. Be2 $18 {White is a clean pawn up.}) (4... Nxe4 $2 {A cheap trick} 5. Bxf7+ (5. Nxf7 Qh4 {is what black hopes for}) (5. Nxe4 $4 d5) 5... Ke7 6. d4 $1 {And white is winning.}) 5. exd5 Na5 (5... Nd4 6. c3 b5 (6... h6 $5 {A new idea played first by John Ludvig Hammer in 2024} 7. cxd4 hxg5 8. d3 $146 {Seems like a fine way to play} exd4 9. Bxg5 Qe7+ 10. Qe2 Qxe2+ 11. Kxe2 $14) 7. Bf1 Nxd5 8. cxd4 Qxg5 9. Bxb5+ Kd8 {Here its easy for white to mess up the move order. If black wants to go exd4, you should be ready for d3 is a way to remember that white should castle first.} 10. O-O $1 (10. Qf3 $2 exd4 11. O-O Rb8 12. Bc4 Bb7 13. d3 Ne3) 10... Bb7 (10... exd4 11. d3 $16) 11. Qf3 Rb8 12. dxe5 Ne3 13. Qh3 Qxg2+ 14. Qxg2 Nxg2 15. d4 {This endgame looks good for white, and yes black has to be careful. but at high depth engines have shown black can hold here, e.g} f6 16. Be2 Nh4 17. f4 Nf5 18. Nc3 Nxd4 19. Rd1 c5 20. Be3 fxe5 21. fxe5 Kc7 22. Rac1 Nxe2+ 23. Nxe2 Bf3 24. Bxc5 Bxc5+ 25. Rxc5+ Kb6 26. Rc2 Rbd8) (5... b5 6. Bf1 Nd4 7. c3 {Position is analyzed via 5...Nd4. Click on the 'Transposition' button or press 'T' to transpose!}) (5... Nxd5 $6 {The proper Fried Liver variation. Often seen as a beginners mistake, it chronically leaves the f7 square weak.} 6. Nxf7 (6. d4 {less critical, but also strong for white.} Nxd4 7. c3 b5 8. Bd3 h6 9. Nxf7 Kxf7 10. cxd4 $14 {Blacks king is still exposed.}) 6... Kxf7 7. Qf3+ Ke6 8. Nc3 Nb4 (8... Ne7 $2 9. d4 {Black is unable to finished their development with the knight on e7.}) 9. O-O c6 {And now modern correspondence games continue like this:} 10. d4 Qf6 11. Qd1 Ke7 12. Re1 h6 13. Rxe5+ Kd8 14. Ne4 Qg6 15. a3 Bf5 16. Ng3 Bxc2 17. Qf3 Nd3 18. Rf5 Bd6 19. Bxd3 Bxd3 20. Qxd3 Kc7 {Where white is up a clean pawn, but black has finally coordinated their pieces. All correspondence games here ended in a draw.}) (5... Bg4 6. Nxf7 $1 $18) 6. Bb5+ c6 7. dxc6 bxc6 8. Bd3 {The modern main line} (8. Qf3 {Highly unusual way of playing, where half of whites pieces are undeveloped, and the other 3 are scattered over the board, still it defends against cxb5, attacks c6, and prepares for Ne4 if h6 is played.} Be7 {Here there is quite a peculiar line} (8... cxb5 {is a new line, where after} 9. Qxa8 {Both} Be7 ({And} 9... Qc7 {lead to sharp and theoretical positions.})) (8... h6 {Another way to sacrifice the exchange.} 9. Ne4 cxb5 10. Nxf6+ gxf6 11. Qxa8 Qd7 $44) 9. Bd3 O-O 10. Nc3 Rb8 $5 11. Bf5 $1 (11. O-O Rb4 $15) 11... Bb7 12. Qh3 (12. Nce4 g6 13. Qh3 h5 14. d3 c5) 12... g6 13. g4 {Difficult to understand what is happening here. Engine continues as follows:} c5 14. Rg1 c4 15. Rg3 Qd4 16. Ne2 Qd5 17. Kf1 h5 18. Nc3 Qc6 19. b4 Kg7 20. b5 Qh1+ 21. Rg1 hxg4 22. Bxg4 Rh8 23. Rxh1 Rxh3 24. Bxh3 Bxh1 25. Bg2 {White is a pawn up, but its difficult to develop properly.}) (8. Be2 {The old main line. it puts the bishop on a safe place, but at the same time whites knight now cannot retreat comfortably} h6 9. Nf3 (9. Nh3 {Famously played by Fischer. whites knight is misplaced, but safe for now. black has many sensible ways to play.} Bb4 $5 $146) 9... e4 10. Ne5 Qd4 (10... Bc5 {and}) (10... Bd6 {are both good.}) 11. f4 Bc5 12. Rf1 {the 'trick' white hopes for, suddenly white is aiming to play with c3-b4 or c3-d4, and blacks pieces seem misplaced. Still, black has good compensation here with the right moves.} Bb6 $1 (12... Qd8 13. d4 $1 Bb6 14. c3) 13. c3 Qd8 14. b4 (14. d4 exd3 15. Qxd3 Qc7 16. Nd2 O-O $44) 14... Nb7 15. Nxc6 Qc7 16. Ne5 O-O {With a very unclear position.}) 8... Nd5 (8... Ng4 {Aiming to force matters.} 9. Ne4 (9. Nh3 {This move has not been played recently, but is also testing against Ng4}) 9... f5 10. Be2 h5 11. h3 fxe4 12. hxg4 Bc5 13. b4 Qd4 14. bxc5 O-O 15. O-O Qxa1 16. Nc3 e3 17. gxh5 exf2+ 18. Rxf2 Rxf2 19. Kxf2 Be6 20. Ba3 Qxd1 21. Bxd1 {This endgame has been reached many times, with mixed results.}) 9. Nf3 (9. h4 {Another modern line, again giving black a lot of options, but none are easy.} h6 (9... Bc5 10. Qf3 f5 11. Nc3 O-O 12. Nxd5 Qxd5 13. Qxd5+ cxd5 14. c3) (9... Be7 10. Qf3 f5 11. Bxf5 Rf8 12. Qh5+ g6 13. Bxg6+ hxg6 14. Qxg6+ Kd7 {This position has also been played quite a bit, and it seems that black has to be more careful than white.}) (9... Qc7 10. Nc3 (10. b3 $5 h6 11. Ne4 f5 12. Nec3 Nf4 13. Bf1 Bb7 14. g3 c5 15. Rg1 Ne6 16. Qh5+ Qf7) 10... h6 11. Nxd5 cxd5 12. Qh5 Bc5 13. b4 Bxb4 14. Nxf7 O-O 15. Nxe5 Rf5 16. Qe8+ Rf8 $10) 10. Qh5 {is the idea} Qf6 11. Ne4 Qe6 {and here white can make a draw with Ng5, or continue with} 12. b3 $13) 9... Bd6 (9... Nf4 $2 {White hasn't castled so can still retreat with} 10. Bf1 $1 $14 {followed by d3 or d4}) 10. O-O {And here black has 2 main ways of playing} (10. Nc3 {A tricky move order. against Nf4 lines it will probably transpose, but against castle it will lead to different positions.} O-O (10... f5 11. Nxd5 cxd5 12. b4 Nc6 13. Bb5 {White scores well here.}) 11. Be2 f5 12. d3 {And theory continues}) 10... Nf4 (10... O-O {The most forcing, and objectively maybe the best. but it is quite complex.} 11. Re1 f5 {[%cal Ge5e4]} 12. Nxe5 Qf6 13. Nf3 g5 14. c4 (14. g3 f4 15. Nc3 fxg3 16. hxg3 Qxf3 17. Qxf3 Rxf3 18. Be4 Rf7 19. Nxd5 cxd5 20. Bxd5 Bb7 21. Bxf7+ Kxf7 $10) (14. Nc3 g4 15. Rb1 $13 {Another way of playing, taking big risks just to get black out of book.}) 14... Nf4 15. Bf1 g4 16. d4 gxf3 17. Qxf3 Ne6 18. Qc3 $13) 11. Re1 Nxd3 (11... O-O $2 12. Bf1 {Again whites bishop escapes.}) 12. cxd3 O-O 13. Nc3 (13. Nxe5 {Leads to a forced draw in multiple ways.} c5 14. Nc3 Bb7 15. b3 Re8 16. Nc4 Rxe1+ 17. Qxe1 Nxc4 18. dxc4 Bxh2+ 19. Kxh2 Qh4+ 20. Kg1 Bxg2 21. Kxg2 Qg4+) 13... Re8 14. Ne4 c5 15. b3 Bf8 16. Ba3 Nc6 $10 {With Nb4 next, black has enough compensation for the pawn.} *
@@ -0,0 +1,18 @@
1
+ [Event "2200+"]
2
+ [Site "?"]
3
+ [Date "2026.05.11"]
4
+ [Round "?"]
5
+ [White "⚪ Repertoire"]
6
+ [Black "Najdorf 6.f4"]
7
+ [Result "*"]
8
+ [FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"]
9
+ [WhiteFideId "-1"]
10
+ [ECO "B92"]
11
+ [Opening "Sicilian Defense"]
12
+ [Annotator "Chess.ceo"]
13
+ [PlyCount "33"]
14
+ [GameId "2231000632463411"]
15
+ [EventDate "2021.??.??"]
16
+ [SourceVersionDate "2025.10.09"]
17
+
18
+ 1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. f4 {Known as the Amsterdam attack, with 6.f4 white immediately starts expanding on the kingside whilst staying flexible with the pieces.} e5 (6... g6 {A rare but good move, its the move Nepomniachtchi sticks to. White has to play concrete:} 7. e5 dxe5 8. fxe5 Nd5 (8... Ng4 9. e6 Bxe6 (9... f5 10. h3 Ne5 11. Be3 Nbc6 12. Nxc6 Qxd1+ 13. Rxd1 bxc6 14. Bf4 Bg7 15. Kf2 {Blacks knight is in trouble [%csl Re5]}) 10. Nxe6 Qxd1+ 11. Nxd1 fxe6 12. Bc4 Nc6 13. c3 {A pleasant endgame for white definitely, but nothing extraordinary.} Nce5 (13... Bh6 14. Bxh6 Nxh6 15. O-O Rf8 16. Nf2) 14. Bxe6 Nd3+ 15. Ke2 Nxc1+ 16. Rxc1 Bh6 17. Rb1 Nf6 18. Nf2 {keep pressin}) 9. Bc4 $5 {A more aggressive option} (9. Qf3 Nxc3 10. Qxc3 Bg7 11. Bf4 O-O 12. O-O-O Qb6 {So far 2 games of Nepo, and here} 13. a4 $146 {Is interesting, planning to go a5 next, blacks queen is in an awkward position.}) 9... Nxc3 10. bxc3 Bg7 (10... Qc7 11. Qe2 b5 (11... Bg7 12. O-O O-O 13. e6 f5 14. Bf4) 12. Bxf7+ (12. Bd5 Qxc3+ 13. Qd2 Qxd2+) 12... Kxf7 13. Qf3+ (13. O-O+ Ke8 14. Be3 e6 15. a4 $44) 13... Ke8 14. e6 Qc4 15. Qf7+ (15. Bb2 Ra7 (15... Nc6 16. Qf7+ Kd8 17. Nxc6+ Qxc6 18. O-O-O+ Kc7 19. c4 Bxe6 $10) 16. Qf7+ Kd8 17. Qf4 Qc7 18. Qf2 Qe5+ 19. Ne2 Rb7 20. Rd1+ Kc7 21. Ba1 $132) 15... Kd8 16. Bf4 Qxc3+ 17. Ke2 Qc4+ 18. Ke1 $10) (10... Nc6 $1 $146 11. Bf4 (11. O-O Nxe5 12. Bb3 Bg7 13. Bf4 O-O 14. Qe2) (11. Nxc6 Qxd1+ 12. Kxd1 {Equal just} Bg4+ 13. Ke1 bxc6 14. Rb1 Bg7 15. Bf4) 11... Bg7 (11... Qa5 12. O-O Qc5 13. Qd3 Bg7 14. Kh1 O-O 15. e6) (11... Na5 12. Bb3) 12. Nxc6 Qxd1+ 13. Rxd1 bxc6 14. Rb1 O-O 15. Ke2 Be6 16. Bxe6 fxe6 17. Rb4) 11. O-O O-O 12. Qd3 {black is cooked} Qc7 (12... Bxe5 13. Bh6 Bf6 14. Bxf8 Qxf8 15. Rae1 Bd7 16. Nb3) (12... Bg4 {difficult to find} 13. Qe4 (13. h3 Nd7 14. hxg4 Nxe5 15. Qe2 Nxc4 16. Qxc4 Rc8 17. Qb4 Rxc3)) (12... Qe8 13. Bg5 Nc6 14. Nxc6 bxc6 15. h4) 13. e6) (6... Qc7 {A tricky waiting move} 7. f5 $1 {A rare move, playing against e6/e5, and at the same time preparing g4 or Bg5} (7. Qf3 $6 {not great because black can still go} e5 {in one go.}) 7... Nc6 {Best move} (7... e5 8. fxe6 fxe6 9. Be2 {Blacks position is not easy} (9. Be3 Be7 (9... d5 10. exd5 Bb4) 10. g4 d5 11. g5 Nxe4 12. Nxe4 dxe4 13. Bg2) 9... Be7 (9... Nc6 10. Nxc6 Qxc6 11. Bg5 Be7 12. Bh5+ g6 13. Bf3) 10. Bh5+ (10. Bg4 {Interesting to make black find Qc4 first} Nxg4 (10... Qc4 11. Be2) 11. Qxg4 Bf6 12. e5 {Here bailout is likely} Bxe5 (12... dxe5 13. Nxe6 Qd7 14. Nd5 Qxd5 15. Nc7+ Kd8 16. Qxc8+ Kxc8 17. Nxd5 Bd8 18. Be3) 13. O-O Qc4 14. Be3 (14. Nce2 Nc6 15. c3) 14... Nc6 15. Rad1 (15. Ne4 Nxd4 16. Rad1 Rf8 17. Rfe1 (17. Qh5+ g6 18. Rxf8+ Kxf8 19. Qxh7 $10)) 15... Nxd4 16. Bxd4 Bd7 17. Ne4 (17. Rf2 O-O-O 18. Ne4 Bc6 19. Bxe5 $10) 17... Bxd4+ 18. Kh1 Qd5 19. c3 Rf8 20. Rfe1 O-O-O 21. Rxd4 Qe5 22. Nxd6+ Kc7 23. Rdd1 Qf4 24. Qxg7 Kb8 25. Nxb7 Rg8 26. Qe7 Rxg2 27. Qd6+) 10... g6 11. Be2 b5 (11... O-O 12. Bh6 Rf7 13. Rf1 $14 {[%cal Gd1d3,Ge1c1]}) 12. a3 e5 13. Nf3 Nbd7 14. Bh6 Ng4 15. Qd2) (7... b5 8. g4 Nbd7 (8... Bb7 9. Bg2 b4 (9... Nbd7) 10. Nd5 Nxd5 11. exd5 $18 Qc4 12. Nc6) 9. a3 (9. Bg2 b4 10. Nd5 Nxd5 11. exd5 g6 12. O-O gxf5 13. a3 Ne5 14. gxf5 Rg8 15. axb4 Bb7) 9... Bb7 10. Bg2 h6 (10... d5 11. Nxd5) 11. O-O {[%csl Rf8]} Qc4 12. Nb3 {[%cal Gb3a5]}) (7... g6 8. g4 d5 {Was played in Yu Yangi - Wei Yi, but after} (8... Bg7 $2 9. g5 Nfd7 10. Nd5 Qd8 11. Be3 $16) (8... b5 9. g5 b4 10. Ncb5 axb5 11. gxf6 Qb7 12. Bg2 gxf5 13. Qe2 Rg8 14. Bf3 Nc6 15. exf5 Nxd4 16. Bxb7 Nxe2 17. Bxa8) 9. Bg2 Nxe4 10. Ndb5 $3 {difficult to spot} (10. Nxd5 Qa5+) 10... axb5 11. Nxd5 Qa5+ 12. b4 {White is winning}) (7... Nbd7 8. g4 b5 {trs} (8... h6 9. Qe2 b5 10. Bf4)) 8. Bg5 Qb6 (8... e6 9. fxe6 fxe6 10. Nxc6) (8... Bd7 9. Bxf6 gxf6 10. Nd5 Qd8 11. Bc4 $16) 9. Nxc6 bxc6 10. Qd2 {black has difficulties developing.} e6 {Korobov} (10... g6 {corr} 11. Na4 (11. Bxf6 exf6 12. O-O-O Rb8 13. b3 gxf5 (13... h5 14. Kb1 Qb4 15. Qe3) 14. exf5 h5 (14... d5 15. Bc4 Ba3+ 16. Kb1 O-O 17. Rhf1 Re8 18. Bxd5 cxd5 19. Nxd5 Qd8 20. Qh6 Rb6 21. Nxb6 Qxb6 22. Rf3 Kh8 23. Rg3 Rg8 24. Rxg8+ Kxg8 25. g4 a5 26. h4) 15. Qe1+ (15. Qe2+ Kd8 (15... Be7 16. Rxd6 Qc5 17. Ne4) 16. Qc4 Be7 17. Qxf7 Qb4 18. Ne2 d5 19. Nd4 Bd7 20. Kb1) 15... Be7 16. Rxd6 Qc5 17. Rd3 Bxf5 18. Re3 Kf8 19. Kb1 Rg8 20. g3 a5 21. Bd3 Be6 22. Rf1) 11... Qb7 (11... Qc7 12. Bxf6 exf6 13. O-O-O) 12. Bxf6 exf6 13. O-O-O Rb8 {[%cal Gb7b4]} 14. a3 gxf5 (14... Be7 15. g4) 15. exf5 Bxf5 16. Bd3 Be6 17. Rhe1 h5 18. Kb1) (10... Qxb2 11. Rb1 Qa3 12. Be2) (10... Rb8 11. Bc4 Qb4 12. b3 $16) 11. O-O-O Rb8 (11... Be7 12. Bxf6 gxf6 (12... Bxf6 13. Na4) 13. Bc4 $16 {[%csl Re7]}) 12. b3 Be7 (12... d5 13. Qe1 Bb4 14. Qg3 Nh5 15. Qf3 Qa5 16. Rd3 Bxc3 17. Rxc3 dxe4 18. Qd1 h6 19. Bh4 O-O 20. Kb2 Nf4 21. Bc4 Qxf5 22. g4 Qe5 23. Bg3) 13. Bf4 (13. Bxf6 gxf6 $13 {Bishop cant go to b3 anymore}) 13... e5 14. Bg5 O-O 15. g4 d5 16. Bxf6 Bxf6 17. exd5 Qb4 18. Qe3 (18. g5 Be7 19. f6 Bc5 20. Kb1 Rd8 21. Qe1 Bg4 22. Be2) 18... e4 19. Nxe4 Qa3+ 20. Kd2 Qa5+ 21. Ke2 (21. Kc1) 21... cxd5 22. Nxf6+ gxf6 23. Kf2) (6... e6 {a common continuation, but usually in the Najdorf, e6 setups give white enough time to put their pieces in good positions, and here its no exception.} 7. Qf3 {And black is already in danger. White just plans to finish development with Be3, long castle and g4.} (7. g4 {is too early:} e5 $1 8. Nf5 Nc6 {[%cal Gg7g6]}) 7... Qc7 (7... Qb6 8. a3 $1 {This way white doesn't have to move their knight from d4.} Nc6 (8... Qxd4 9. Be3) (8... Be7 9. Bd3 O-O 10. Be3 Qxb2 11. Kd2 $1 {Threatening Rhb1 winning the queen, and after} Qb6 12. Nxe6 $18 {White wins the exchange.}) 9. Nxc6 bxc6 10. e5 $14) (7... Be7 8. Be3) (7... e5 {Rare move suggested by the engine, but after} 8. fxe5 dxe5 9. Nf5 $14 {Whites position is pleasant.}) 8. g4 {White has easy play} Nc6 (8... b5 9. g5 Nfd7 10. a3 Bb7 11. Be3 Nc6 12. Bh3 $16) 9. Nxc6 bxc6 10. g5 Nd7 11. Bd2 $16 {[%cal Ge1c1,Gh2h4]}) (6... Nbd7 {Just like e6, this move feels a bit passive, but here the upside is that black can still go e5 in one go.} 7. Be3 (7. Be2 e5 (7... g6 8. Be3) (7... b5 8. O-O Bb7 9. Bf3 e6 (9... e5)) 8. fxe5 Nxe5 {A typical Najdorf structure, which in this case is fine for black.}) (7. g4 Nc5 8. f5 Nfxe4 9. Nxe4 Nxe4 10. Bg2 d5 11. O-O e6 12. fxe6 Bxe6 13. Nxe6 fxe6 14. Be3) (7. Qf3 $6 e5 $10) 7... Nc5 (7... e5 8. Nf5 {is good for white because our bishop on e3 prevents Nc5}) (7... e6 $2 {Played but again here its too slow} 8. g4 $16) (7... g6 8. Be2 {Important to start with this, to not allow ideas connected with Ng4} (8. Qe2 Bg7 (8... e5 9. fxe5 dxe5 10. Nb3 Bb4 $13 11. Qf3) 9. O-O-O O-O 10. g4 e5 11. Nb3 exf4 12. Bxf4 Ne8 13. Qd2 Ne5 14. h3 Be6 15. Be2) 8... Bg7 (8... Qc7 9. O-O Bg7 (9... b5 10. e5) 10. g4 h6 (10... Nc5 11. Bf3 h5 12. g5 (12. gxh5 Bh3 13. hxg6 fxg6) 12... Ng4 13. Nd5 Qd8 14. f5 Nxe3 15. Nxe3 Be5) 11. g5 hxg5 12. fxg5 d5 13. Rf4 Nxe4 14. Nxd5 Qd6 15. Nf3 f5 16. gxf6 Ndxf6 17. Nxf6+ Nxf6 18. Qxd6 (18. Rd4 $36) 18... exd6 19. Bd3 $14) 9. Qd2 O-O 10. O-O-O $14 {White has easy ideas. [%cal Gh2h4,Gh4h5,Ge2f3]}) (7... Qc7 8. g4 $1 Nc5 9. Nd5 $1 Nxd5 10. exd5 {+0,5}) 8. Bc4 {Most testing} (8. Bd3 {Also possible, probably with a slightly better position}) 8... Bg4 (8... Ncxe4 $2 {too greedy:} 9. Nxe4 Nxe4 10. Qh5 g6 11. Qd5 e6 12. Qxe4 d5 {black wins back the piece but after} 13. Qf3 dxc4 14. O-O-O {White has a crushing attack [%cal Gf4f5,Gh1e1]}) (8... e6 9. e5) 9. Nf3 Qc7 (9... b5 10. e5 $1 bxc4 11. exf6 gxf6 12. h3 {Blacks position is very difficult to handle, with white soon finishing development. [%cal Gd1e2,Ge1c1]}) 10. h3 Bxf3 11. Qxf3 e6 12. Bxc5 Qxc5 13. Bb3 $14 O-O-O 14. O-O-O Nd7 15. Kb1 g6 16. Ne2 Bg7 17. c3) (6... Nc6 {Playing a Rauzer with the inclusion of f4-a6} 7. Be3 (7. e5 {Pleasant endgame} dxe5 8. Nxc6 Qxd1+ 9. Nxd1 bxc6 10. fxe5 Nd5 (10... Nd7 11. e6) (10... Ng4 11. Bf4 g5 $1 12. Bxg5 h5 {odd looking} 13. h3 Nxe5 14. Nc3 {[%cal Ge1c1]}) 11. c4 (11. Ne3) 11... Nb4 (11... Nb6 12. Be3) 12. Ne3 a5 13. a3 Na6 14. b4) (7. Nxc6 bxc6 8. e5 Nd7 9. Qf3 d5 10. Bd3 e6 11. O-O) (7. Be2 g6 8. Nxc6 bxc6 9. e5 Nd7 10. exd6 Bg7 11. O-O O-O $44) 7... g6 8. Qd2 (8. h3 Bg7 9. Qf3 Nxd4 (9... O-O 10. O-O-O Bd7 11. Qf2 Nxd4 12. Bxd4 Bc6 13. Bd3) 10. Bxd4 b5 11. O-O-O Bb7 12. h4 h5 13. Nd5 Bxd5 14. exd5 O-O 15. Bxf6 Bxf6 16. Kb1 Qa5 17. c3 b4 18. c4) 8... Bg7 9. O-O-O O-O 10. Be2 Bd7 11. Bf3 Rc8 12. Nxc6 bxc6 13. Rhe1 Qa5 14. e5 dxe5 15. fxe5 Qxe5 16. Bd4 Qa5 17. Rxe7 Be6 18. Qe3 Qb4 19. Rxe6 fxe6 20. Qxe6+ Kh8 21. a3 Qb8 22. Bxc6 Qxh2 23. Bf3) 7. Nb3 $5 {A move that has picked up some steam lately, with just 400 games, many black players will still be surprised by this move.} (7. Nf3 Nbd7 8. a4 {Is the main line.}) 7... Nc6 $1 {Probably the safest move, it prevents the endgame with fxe5, and at the same time keeps the c8 bishops diagonal open preventing g4.} (7... Be7 {The most played move, and also in the Najdorf style, staying flexible with the b8 knight for now.} 8. fxe5 $1 {Quite unexpected, because usually endgames are fine for black in the Sicilian.} dxe5 9. Qxd8+ Bxd8 10. Be3 {But this endgame is not easy for black, their main problem here is the bishop on c8, it doesn't have a good square to develop to.} Nbd7 (10... Nc6 11. O-O-O (11. Be2 {allows} Bg4 $10) 11... O-O (11... Bg4 12. Rd3 $14 {b7 is weak and also we can h3 next asking black the difficult question as to where to go. [%cal Gb3c5,Gh2h3] [%csl Rb7]}) 12. Be2 b5 {Was played in Lodici-Stella, but here after a calm waiting move like} 13. a3 $14 {Black can't finish their development.}) (10... O-O 11. O-O-O b5 12. Be2 Bg4 (12... Bb7 13. a3) 13. Rhe1) (10... Bd7 $5 {Interesting way of playing [%cal Gd7c6]} 11. Be2 Bc6 12. Bf3 Nbd7 13. O-O-O {Still black is passive here} Rc8 (13... a5 14. Nd2) (13... O-O 14. g4 $36 {[%cal Gh2h4,Gg4g5]}) 14. Kb1 b5 (14... h5 15. h3 Kf8 16. g4 hxg4 17. hxg4 Rxh1 18. Rxh1 Kg8 19. g5 Nh7 20. Rg1 f5 21. gxf6 Nhxf6 22. Nd5) 15. a3 $14) (10... Be6 {Important to pay attention here, if black gets to play Nbd7 they got their perfect setup} 11. Nc5 $1 b5 (11... b6 12. Nxe6 fxe6 13. O-O-O {White was clearly better in Maurizzi-Lamard}) (11... Bc8 $1 12. Bd3 b6 13. Nb3 {0.00SF 0.2 Lc0} Nbd7 14. Nd2 Be7 15. Rf1) 12. Nxe6 fxe6 13. a4 $1 (13. a3 $2 Nc6 {[%cal Ga8b8,Gd8b6,Ge8e7]}) 13... b4 14. Na2 $14) (10... h5 {Cool waiting move} 11. h3 {Seems good enough} (11. O-O-O $6 Bg4 $1 {This is the trick, black gets to go Nbd7 next move})) (10... b5 $2 11. a4 b4 12. Nd5 Nxd5 13. exd5 $16 {Long castle next, its difficult for black to coordinate.}) (10... Ng4 11. Bg1 Nf6 {engine likes this} 12. Bd3) 11. Be2 {Waiting with long castle makes sense, so that b5 can be answered with a4} b5 (11... b6 12. O-O-O Bb7 13. Rhf1 Rc8 14. a4 $14) 12. a4 b4 13. Nd5 Nxd5 14. exd5 $16 {Same as against 10...b5, this position is good for white.}) (7... Nbd7 {Either a good move, or a dubious one depending if black knows their next move} 8. g4 d5 $1 (8... h6 {Most played, but passive:} 9. g5 hxg5 (9... Ng8 $7 10. Qh5 g6 11. Qh4 Bg7 12. Qg3 Ne7 13. gxh6 Bxh6 14. h4 $36) 10. fxg5 Nh5 11. Qf3 {Black is in big trouble. [%cal Gc1e3,Ge1c1]}) 9. exd5 Nb6 (9... Bb4 $2 10. Bg2 Nb6 11. fxe5 Nfxd5 12. O-O $18 {White won 2/2 here.}) 10. g5 (10. Bg2 Bxg4 11. Qd3 Bd6 12. f5) 10... Nfxd5 11. Bg2 Nxf4 (11... Bb4 12. O-O) 12. Bxf4 exf4 13. Qxd8+ (13. O-O Qxd1 14. Raxd1 Be7 15. Rxf4 O-O 16. h4) 13... Kxd8 {And the engines quickly claim complete equality, but after} 14. a4 {Black is the one who has to be careful} Kc7 $146 {Best move according to the engine, but requires steel nerves:} (14... Bg4 {Played in Bulmaga - Dinara Wagner} 15. O-O Bd6 16. h3 $146 Be6 (16... Bh5 17. Na5) 17. Rad1 Nc4 18. Ne4 Kc7 19. Nxd6 Nxd6 20. Nc5 $14) 15. a5 Nc4 16. Nd5+ Kb8 17. O-O Bd6 18. Ra4 (18. Rad1) 18... Ne3 19. Nxe3 fxe3 20. Rxf7 $36 {Apparently an equal position, but its definitely black who has to remain careful.} Ra7 $1 21. Rd4 (21. Nd4 Bc5 (21... e2 22. Kf2) 22. Kf1) 21... e2 (21... Re8 22. Rf1) 22. Re4 b6 23. Rxa7 Kxa7 24. Rxe2 Rf8 25. c3) (7... Qc7 8. Be2 {Blacks position is not easy} b5 (8... Nbd7 9. O-O b5 (9... Be7 10. g4 $14 (10. Kh1 b6 $13 (10... O-O 11. g4) (10... b5 11. a4 b4 12. Nd5 Nxd5 13. exd5 O-O 14. Bd2 Rb8 15. c4) (10... h6 {decent} 11. a4 O-O 12. a5) 11. fxe5 dxe5 12. Nd5 Nxd5 13. Qxd5 O-O 14. Rxf7 Rxf7 15. Bc4 Kh8 16. Qxf7 Nf6 17. Bg5) 10... Qc6 11. Bf3) (9... exf4 10. Bxf4 Be7 11. Qe1 $14 {[%cal Gg1h1,Gb3d4,Ge1g3]}) 10. a4 b4 11. fxe5 Nxe5 12. Nd5 Nxd5 13. exd5 g6 14. Kh1 Bg7 15. Bd2 Bf5 16. Rxf5 {EA} gxf5 17. Bxb4 (17. Nd4 Ng4 18. Bxg4 Bxd4 19. Bxf5 Bxb2 20. Qe2+ Be5 21. Re1 a5 22. Qh5 h6 23. h3) 17... Ng4 18. Bxg4 fxg4 19. Qe2+ Be5 20. Na5 O-O 21. Qxg4+ Kh8 22. Qc4) (8... Be6 $2 9. g4 $16) (8... Be7 $2 9. g4 $16) 9. O-O Bb7 (9... Nbd7 {trs}) 10. a4 b4 11. Nd5 Nxd5 (11... Bxd5 12. exd5 Nbd7 13. g4 $36) 12. exd5 Nd7 13. fxe5 {V Nesty} (13. c4 bxc3 14. bxc3 Be7 15. c4 Bf6 (15... O-O 16. fxe5 Nxe5 17. Be3 $14) 16. fxe5 (16. f5 O-O 17. Be3) 16... Bxe5 17. Rb1 O-O 18. Bd2) 13... dxe5 (13... Nxe5 $2 14. a5 $18) 14. c4 (14. Bg5) 14... bxc3 15. bxc3 Nb6 (15... Bd6 16. c4 O-O 17. Be3 Nc5 18. Kh1 a5 19. Qc2 $18) (15... Qxc3 16. Bg5 (16. d6 Rd8 (16... Rb8 17. Ba3) 17. Ba3 Nf6 18. Nc5 (18. Rb1 Qe3+ 19. Kh1 Bxd6 20. Bxd6 Rxd6 21. Qxd6 Bxg2+ 22. Kxg2 Qxe2+ $10) 18... Bc6 19. Qc1) 16... Bd6 17. Kh1 O-O 18. Rc1 Qb4 19. Rc4 Qb6 20. a5 Qa7 21. Bd3 g6 22. Bf5 gxf5 23. Rh4 f6 24. Rxh7 Rf7 25. Rxf7 Kxf7 26. Qh5+ Ke7 27. Qh7+ Ke8 28. Qg6+ Ke7 29. Bxf6+ Nxf6 30. Qg7+ Ke8 31. Qxf6 Bxd5 32. Qxd6 Rd8 33. Qxe5+ Qe7 34. Qg3) 16. c4 Nxc4 17. Kh1 (17. Ra2) (17. Qd3 Rc8 18. Ra2) 17... Be7 (17... Bb4 18. a5 Rc8 19. Ra4) (17... Bd6 18. a5) 18. Qd3 Nd6 19. Bb2 Bf6 20. Rac1 Qd8 21. Ba3) 8. Bd3 {The safest move.} (8. f5 {Going for complications, but quite risky} Be7 (8... b5 9. a4 (9. Bg5 Be7 10. Qd3 Bb7 11. O-O-O Rc8 12. Bxf6 Bxf6 13. Qxd6 Qxd6 14. Rxd6 Ke7 15. Rd1 Nd4 16. Kb1) 9... bxa4 10. Rxa4 Be7 11. Bc4) (8... d5 9. Bg5 Bb4 (9... Nb4 10. a3 d4 11. axb4 Bxb4 12. Bxf6 Qxf6 13. Bb5+ Ke7 14. Qf3 Be6 15. Nxd4 axb5 16. Rxa8 Rxa8 17. Nxe6 Bxc3+ 18. Qxc3 Qh4+ 19. Kd2 Qf2+ 20. Kd3 fxe6 21. Qxe5 Rd8+ 22. Kc3 Qe3+) (9... dxe4 10. Qxd8+ Kxd8 11. Bc4 Ke8 12. Bxf6 gxf6 13. Nxe4 Be7 14. Rf1) 10. Bxf6 Qxf6 (10... gxf6 11. Qxd5 Qxd5 12. exd5 Ne7 13. O-O-O) 11. Qxd5 Qh6 12. Bc4) 9. Bd3 (9. Bg5 Nxe4 10. Nxe4 Bxg5 11. Nxd6+ Ke7 $15 12. Qh5 Qxd6 13. Qxg5+ Qf6 14. Qxf6+ Kxf6 15. Bd3) (9. g4 h6 (9... Nd7) 10. Be3 b5 (10... h5 11. h3 hxg4 12. Qd2) 11. h4 Bb7 12. Bg2 b4 13. Nd5 Nxd5 14. exd5 Bxh4+ 15. Rxh4 Qxh4+ 16. Bf2 Qh2 17. dxc6 Qxg2 18. cxb7 Qxb7 19. Qxd6 Qe4+ 20. Kf1) (9. Nd5 O-O 10. Bd3) 9... O-O (9... g6 10. Bg5 gxf5 11. exf5 d5 12. O-O Rg8 13. Bh4 b5 14. Kh1 Bb7 15. Bxf6 Bxf6 16. Nc5 Ra7 17. Qh5 Ne7 18. Qh6 $18 {Mamedov-Volokitin}) 10. Be3 {Movahed & Idani} (10. a3 $146 d5 (10... b5 11. g4 Nd7 12. Rg1) 11. O-O dxe4 12. Nxe4 Nd4 (12... Nxe4 13. Bxe4) 13. Be3 Nxb3 14. cxb3 Bd7 15. Nxf6+ Bxf6 16. Be4 Bc6 17. Bxc6 bxc6 18. Rc1) (10. Nd5 Nxd5 11. exd5) (10. O-O Nb4 11. Bg5 d5 12. Bxf6 Bxf6 13. Nxd5 Nxd5 14. exd5 Qxd5 15. Qe2) 10... Re8 (10... b5 11. Nd5 Bb7 (11... Nxd5 12. exd5 Na5 (12... Nb4 13. Be4) 13. O-O Nc4 14. Bxc4 bxc4 15. Nd2 a5 16. Qg4) 12. O-O Nxd5 13. exd5 Nb4 14. Be4 Rc8 15. c3 Rc4 16. Bf3 e4 17. cxb4 exf3 18. Na5 Rxb4 19. Nxb7 Qc7 20. Qd2 Rc4 21. Na5 Rc2 22. Qd3 Rxg2+ 23. Kh1 Qxa5 24. Rxf3 Rg4 (24... Qb4 25. Kxg2 Qxb2+ 26. Qd2 Qxa1 27. Bd4 Qb1 28. Bxg7 Rc8 29. Rg3 Qe4+ 30. Kg1 $10) 25. h3 Rh4 26. f6) (10... a5 11. O-O (11. a3) 11... a4 12. Nd2 Nb4 13. Nc4) 11. Qf3 a5 (11... d5 12. Nxd5 Nxd5 13. exd5 e4 14. Bxe4) (11... Nb4 12. O-O-O Nxd3+ 13. Rxd3 b5 14. Bg5 b4 15. Bxf6 Bxf6 16. Nd5) (11... b5 12. O-O-O Bb7 13. Kb1 Nb4 (13... Rc8 14. g4 b4 15. Nd5 Nxd5 16. exd5) 14. Bg5) 12. O-O a4 (12... Nb4) 13. Nd2 a3 14. b3) (8. Be2 Be7 9. O-O O-O (9... Be6 10. f5) (9... exf4 10. Bxf4 O-O 11. Qe1 Be6 12. Rd1 Qc7 13. Kh1 Ne5 14. Nd4 b5 15. a3 Rac8 16. Qg3) 10. Kh1 b5 (10... exf4 11. Bxf4 {[%cal Gd1e1,Ga1d1]}) (10... Re8 11. a4 h6 12. Be3 exf4 13. Rxf4 Be6 14. Nd5 Nd7) 11. a4 b4 (11... Bb7 12. axb5 axb5 13. Rxa8 Qxa8 14. Bxb5 Na7 15. Bd3 Nxe4 16. Nxe4 Bxe4 17. Bxe4 Qxe4 18. Re1 Qf5 19. Na5) 12. Nd5 Bb7 (12... Nxe4 13. Bf3 f5 14. Be3 Be6 15. g4) 13. Be3 Nxd5 (13... Nxe4 14. Bb6 Qd7 (14... Qc8 15. fxe5 dxe5 16. Bd3 f5 17. Na5) 15. Bf3 f5 16. Bxe4 fxe4 17. Nc5 Qc8 18. Nxb7 Qxb7 19. fxe5 Rxf1+ 20. Qxf1 Nxe5 21. Rd1) 14. exd5 Na5 15. Nxa5 Qxa5 16. fxe5 dxe5 17. d6) (8. Bc4 Be7 9. O-O O-O 10. f5 b5 11. Bd5 Bb7 12. Be3 Rc8 13. Rf3 Kh8 (13... Nxd5) (13... Ng4 14. Kh1 Nxe3 15. Rxe3) 14. Rh3) 8... Be7 9. O-O (9. f5 O-O 10. O-O Nb4 11. Bg5) (9. Nd5 Nxd5 (9... exf4 {Black is fine here also}) 10. exd5 Nb4 11. Be4 f5 12. Bf3 a5 13. a4 Qb6 (13... O-O 14. c3 Na6 15. O-O) 14. c3 Na6 15. Nd2 exf4 (15... Qc5 16. Nb3) 16. Nc4 Qc7 17. b3 O-O 18. Bxf4) 9... O-O (9... exf4 {Brkic} 10. Bxf4 (10. Nd5 Nxd5 (10... g5 11. Bd2) 11. exd5 Ne5 12. Bxf4 O-O) 10... O-O 11. Qe1 {Equal position can just follow standard pattern [%cal Ga1d1,Gg1h1,Ge1g3]} Ne5 (11... Be6 12. Rd1 Nd7 13. Be2 Nde5 14. Nd5 $14) 12. Rd1 Be6 (12... Qc7 13. Kh1) 13. Kh1 Nfd7 14. Nd4 Rc8 15. Be2 Re8 (15... Qb6 16. b3) (15... h6 16. Qg3 Bh4 17. Qe3 Re8) 16. Qg3 Bh4 17. Qe3 Nc4 (17... Bf6 18. Qg3) (17... h6 18. a3) 18. Bxc4 Bxc4 19. Rg1) (9... Nb4 10. Be2 O-O 11. Kh1) 10. Nd5 $5 {Although blacks positions is really fine here, at least there are some complications.} (10. h3) (10. Kh1 exf4 11. Bxf4 Re8 12. Qe1) 10... Nxd5 (10... Re8 11. Kh1 (11. f5 Nxd5 12. exd5 e4 13. Bxe4 Bf6 $44) 11... exf4 (11... Nxd5 12. exd5 Nb4 13. Be4 f5 14. Bf3 a5 15. c3 Na6 16. a4 Bf6 17. Be3) 12. Bxf4 Nxd5 13. exd5 Ne5 14. Bxe5 dxe5 15. Bxh7+ Kxh7 16. Qh5+ $10) (10... exf4 11. Nxe7+ Qxe7 12. Bxf4 h6 13. Qe1 $14) (10... h6 11. f5 $14) 11. exd5 Nb4 12. Be4 f5 13. Bf3 a5 14. c3 Na6 15. a4 Qb6+ (15... Bf6) 16. Kh1 Nc5 (16... e4 17. Be2 Bf6 18. Bb5 Rf7 19. Qe2) 17. Nxc5 (17. Ra3) 17... Qxc5 18. Re1 Qc7 19. Qb3 exf4 (19... e4 20. Be2) 20. Bxf4 g5 21. Be3 Bf6 22. g3 Qg7 23. Re2 Bd7 24. Qxb7 Be5 25. Bxg5 $10 *