Games played by moving a token or pieces on a graph. Some are solved by matching theory or a structural characterization in polynomial time; close relatives are PSPACE-complete.

GameRuleAnswerComplexity
undirected vertex geographya token starts on (visited); players alternately move it to an unvisited neighbour; who cannot move losesthe first player wins iff every maximum matching covers ( in Gallai–Edmonds)
undirected edge geographythe same, but edges may not be reusedPSPACE-complete (Fraenkel, Scheinerman and Ullman, 1993)
directed vertex / edge geographyon a digraphPSPACE-complete (Schaefer 1978; Lichtenstein and Sipser 1980 for planar)
tokens moving on a DAG, sum of several tokensmove one token along an arcXOR of Grundy values of the token positions: Sprague–Grundy
tokens on a graph with cyclesgeneralized Sprague–Grundy / retrogradeLoopy Games
cops and robber (one cop, both may stay; the cop wins by landing on the robber)the cop wins iff the graph is dismantlable (Nowakowski–Winkler, Quilliot, 1983)
Shannon switching game (Short claims edges to connect ; Cut deletes edges)Short, moving second, wins iff some subgraph containing has two edge-disjoint spanning trees (Lehman, 1964)matroid union: Matroid Intersection
Hex, Chompstrategy stealingChomp and Hex

Undirected vertex geography

The Gallai–Edmonds decomposition splits the vertices into (missed by some maximum matching), and (the rest); Blossom and gallaiEdmonds are in General Matching, with their proofs.

// Uses Blossom and gallaiEdmonds from the General Matching note. Token on s, s already visited.
bool geographyFirstWins(int n, const vector<pair<int, int>>& edges, int s) {
    Blossom B(n);
    for (auto [u, v] : edges) B.addEdge(u, v);
    B.run();
    return gallaiEdmonds(B)[s] != 0;                     // first player wins iff s is covered by every maximum matching
}

Cops and robber

The cop chooses a start vertex, then the robber; then they alternate, the cop first, each moving along an edge or staying put. The cop wins by occupying the robber’s vertex. A vertex is a corner if some has (closed neighbourhoods); a graph is dismantlable if corners can be deleted one by one down to a single vertex.

bool copWin(const vector<vector<int>>& adj) {               // connected graph; greedy dismantling, O(n^3) bitsets
    int n = sz(adj); vector<bitset<512>> N(n); vector<char> alive(n, 1);
    for (int v = 0; v < n; v++) { N[v][v] = 1; for (int u : adj[v]) N[v][u] = 1; }
    for (int left = n; left > 1; left--) {
        int corner = -1;
        for (int r = 0; r < n && corner < 0; r++) if (alive[r])
            for (int w = 0; w < n; w++) if (w != r && alive[w] && (N[r] & ~N[w]).none()) { corner = r; break; }
        if (corner < 0) return false;
        alive[corner] = 0;
        for (int v = 0; v < n; v++) N[v][corner] = 0;
    }
    return true;
}