[Google Sheets] Importer un fichier PGN (échecs)

Bonjour,

Un fichier .pgn pour Portable Game Notation est un fichier texte structuré pour enregistrer les jeux d'échecs. La structure est la suivante :

[Event "Live Chess"]
[Site "Chess.com"]
[Date "2020.12.09"]
[Round "-"]
[White "GMWSO"]
[Black "Hikaru"]
[Result "1-0"]
[CurrentPosition "8/1k1K4/2Q5/1N6/8/6B1/8/8 b - -"]
[Timezone "UTC"]
[ECO "B06"]
[ECOUrl "https://www.chess.com/openings/Modern-Defense-Standard-Line-3...c6"]
[UTCDate "2020.12.09"]
[UTCTime "20:25:00"]
[WhiteElo "3099"]
[BlackElo "3355"]
[TimeControl "60+1"]
[Termination "GMWSO won by checkmate"]
[StartTime "20:25:00"]
[EndDate "2020.12.09"]
[EndTime "20:29:58"]
[Link "https://www.chess.com/game/live/5927279266"]

1. e4 {[%clk 0:01:01]} 1... g6 {[%clk 0:01:01]} 2. d4 {[%clk 0:01:01.3]} 2... Bg7 {[%clk 0:01:01.9]} 3. Nc3 {[%clk 0:01:01.1]} 3... c6 {[%clk 0:01:02.4]} 4. h3 {[%clk 0:01:01.3]} 4... d5 {[%clk 0:01:03]} 5. e5 {[%clk 0:01:01.8]} 5... f6 {[%clk 0:01:03.1]} 6. f4 {[%clk 0:01:02.4]} 6... Nh6 {[%clk 0:01:03.4]} 7. Nf3 {[%clk 0:01:03.2]} 7... O-O {[%clk 0:01:03.2]} 8. Bd3 {[%clk 0:01:03.7]} 8... Bf5 {[%clk 0:01:03.1]} 9. O-O {[%clk 0:01:03.1]} 9... Nd7 {[%clk 0:01:03.1]} 10. Ne2 {[%clk 0:01:02]} 10... Be4 {[%clk 0:01:01.8]} 11. Bxe4 {[%clk 0:01:00.9]} 11... dxe4 {[%clk 0:01:02.2]} 12. Nd2 {[%clk 0:01:01.4]} 12... f5 {[%clk 0:01:02.8]} 13. Nc4 {[%clk 0:01:01.2]} 13... Nb6 {[%clk 0:01:02.3]} 14. Ne3 {[%clk 0:01:00.1]} 14... Nd5 {[%clk 0:01:02.4]} 15. c4 {[%clk 0:01:00.1]} 15... Nxe3 {[%clk 0:01:01.4]} 16. Bxe3 {[%clk 0:01:01]} 16... e6 {[%clk 0:01:02.1]} 17. Qb3 {[%clk 0:01:00.9]} 17... Qe7 {[%clk 0:01:02.1]} 18. Rad1 {[%clk 0:01:01.3]} 18... Rfd8 {[%clk 0:01:02.4]} 19. Rd2 {[%clk 0:00:58.3]} 19... Nf7 {[%clk 0:00:59.1]} 20. Rfd1 {[%clk 0:00:58.3]} 20... g5 {[%clk 0:00:55.7]} 21. d5 {[%clk 0:00:53.2]} 21... exd5 {[%clk 0:00:52]} 22. cxd5 {[%clk 0:00:54.1]} 22... gxf4 {[%clk 0:00:52.7]} 23. Bxf4 {[%clk 0:00:49.2]} 23... cxd5 {[%clk 0:00:48.4]} 24. Rxd5 {[%clk 0:00:49.7]} 24... Rxd5 {[%clk 0:00:49.1]} 25. Rxd5 {[%clk 0:00:49.5]} 25... Rd8 {[%clk 0:00:49.8]} 26. Nd4 {[%clk 0:00:48.8]} 26... Rxd5 {[%clk 0:00:34.2]} 27. Qxd5 {[%clk 0:00:49.7]} 27... Qd8 {[%clk 0:00:35]} 28. Qxd8+ {[%clk 0:00:45.2]} 28... Nxd8 {[%clk 0:00:35.7]} 29. Nxf5 {[%clk 0:00:40.3]} 29... Ne6 {[%clk 0:00:35.3]} 30. Bg3 {[%clk 0:00:39.3]} 30... Bf8 {[%clk 0:00:35.8]} 31. Nd6 {[%clk 0:00:36]} 31... e3 {[%clk 0:00:33.5]} 32. Kf1 {[%clk 0:00:30.2]} 32... Nd4 {[%clk 0:00:33.8]} 33. Bf4 {[%clk 0:00:30.6]} 33... e2+ {[%clk 0:00:32]} 34. Kf2 {[%clk 0:00:30.8]} 34... Be7 {[%clk 0:00:26.4]} 35. g3 {[%clk 0:00:28.7]} 35... b6 {[%clk 0:00:24.6]} 36. Be3 {[%clk 0:00:26.7]} 36... Nc6 {[%clk 0:00:25.1]} 37. Bf4 {[%clk 0:00:22.8]} 37... Nd4 {[%clk 0:00:23.5]} 38. Be3 {[%clk 0:00:20.7]} 38... Nc6 {[%clk 0:00:24]} 39. Kxe2 {[%clk 0:00:21.1]} 39... Nxe5 {[%clk 0:00:24]} 40. Nc8 {[%clk 0:00:21.8]} 40... Bf6 {[%clk 0:00:23.4]} 41. Nxa7 {[%clk 0:00:21.3]} 41... Nc4 {[%clk 0:00:23.8]} 42. b3 {[%clk 0:00:21]} 42... Nd6 {[%clk 0:00:24.3]} 43. Bxb6 {[%clk 0:00:20.5]} 43... Ne4 {[%clk 0:00:25.2]} 44. Kf3 {[%clk 0:00:20]} 44... Nc3 {[%clk 0:00:25.8]} 45. a4 {[%clk 0:00:19.9]} 45... Nd5 {[%clk 0:00:25.9]} 46. a5 {[%clk 0:00:20.1]} 46... Nb4 {[%clk 0:00:26]} 47. Bc5 {[%clk 0:00:19.8]} 47... Na6 {[%clk 0:00:16.8]} 48. b4 {[%clk 0:00:19.6]} 48... Be5 {[%clk 0:00:16.3]} 49. Nc6 {[%clk 0:00:19.2]} 49... Bc7 {[%clk 0:00:17]} 50. Be3 {[%clk 0:00:18.5]} 50... Bd6 {[%clk 0:00:16.9]} 51. b5 {[%clk 0:00:18.5]} 51... Nc7 {[%clk 0:00:17.5]} 52. b6 {[%clk 0:00:18.6]} 52... Nd5 {[%clk 0:00:18.2]} 53. b7 {[%clk 0:00:18.4]} 53... Kf7 {[%clk 0:00:18.8]} 54. b8=Q {[%clk 0:00:17.1]} 54... Bxb8 {[%clk 0:00:19.3]} 55. Nxb8 {[%clk 0:00:17.9]} 55... Ke6 {[%clk 0:00:19.7]} 56. a6 {[%clk 0:00:18.3]} 56... Nc7 {[%clk 0:00:20.4]} 57. a7 {[%clk 0:00:18.7]} 57... Kd5 {[%clk 0:00:21.3]} 58. Bf4 {[%clk 0:00:18.6]} 58... Na8 {[%clk 0:00:22.2]} 59. Na6 {[%clk 0:00:19]} 59... Kc6 {[%clk 0:00:22.3]} 60. Nc7 {[%clk 0:00:19.9]} 60... Nb6 {[%clk 0:00:22.2]} 61. a8=Q+ {[%clk 0:00:19.2]} 61... Nxa8 {[%clk 0:00:23.1]} 62. Nxa8 {[%clk 0:00:19.7]} 62... Kd7 {[%clk 0:00:24]} 63. Nc7 {[%clk 0:00:20.5]} 63... Ke7 {[%clk 0:00:24.3]} 64. g4 {[%clk 0:00:21.4]} 64... Kf6 {[%clk 0:00:24.7]} 65. g5+ {[%clk 0:00:22.3]} 65... Kg6 {[%clk 0:00:25.2]} 66. Kg4 {[%clk 0:00:23.2]} 66... Kf7 {[%clk 0:00:26]} 67. h4 {[%clk 0:00:23.8]} 67... Ke7 {[%clk 0:00:26.9]} 68. h5 {[%clk 0:00:24.5]} 68... Kf7 {[%clk 0:00:27.8]} 69. h6 {[%clk 0:00:24.6]} 69... Kg6 {[%clk 0:00:28]} 70. Ne6 {[%clk 0:00:24.3]} 70... Kf7 {[%clk 0:00:28.9]} 71. Nd4 {[%clk 0:00:24.9]} 71... Kg6 {[%clk 0:00:29.4]} 72. Nf3 {[%clk 0:00:25.3]} 72... Kf7 {[%clk 0:00:30.3]} 73. Bg3 {[%clk 0:00:25.6]} 73... Ke6 {[%clk 0:00:31.1]} 74. g6 {[%clk 0:00:25.8]} 74... hxg6 {[%clk 0:00:31.5]} 75. h7 {[%clk 0:00:26.7]} 75... Kd5 {[%clk 0:00:32.1]} 76. h8=Q {[%clk 0:00:26.7]} 76... Kc6 {[%clk 0:00:33]} 77. Qe5 {[%clk 0:00:26.7]} 77... Kb7 {[%clk 0:00:33.4]} 78. Qd6 {[%clk 0:00:26.7]} 78... g5 {[%clk 0:00:33.9]} 79. Kxg5 {[%clk 0:00:26]} 79... Ka7 {[%clk 0:00:34.2]} 80. Kf5 {[%clk 0:00:26.8]} 80... Kb7 {[%clk 0:00:34.3]} 81. Ke6 {[%clk 0:00:27.7]} 81... Ka7 {[%clk 0:00:34.9]} 82. Kd7 {[%clk 0:00:28.6]} 82... Kb7 {[%clk 0:00:35.5]} 83. Nd4 {[%clk 0:00:29.5]} 83... Ka7 {[%clk 0:00:35.7]} 84. Nb5+ {[%clk 0:00:29.7]} 84... Kb7 {[%clk 0:00:03.5]} 85. Qc6# {[%clk 0:00:30.6]} 1-0

PGN a été conçu vers 1993, par Steven J. Edwards.

Comment importer les données. Nous pouvons avoir à faire à 2 types de fichiers :

Google Sheet étant basé sur une version de javascript, j'ai pris comme solution la transformation des données en format json, ce qui est plus facile ensuite à traiter.

Ce qui donne :

/**
 * Parse a PGN file inside json.
 *
 * @param {range} url url 
 * @param {range} xpath data to be fetched 
 * @param {boolean} sequence if true sequence will be fetched 
 * @customfunction
 */
function readPGN(url,xpath,sequence) {
  var result=[]
  var reponse = UrlFetchApp.fetch(url);
  var json = reponse.getContentText();
  var data = JSON.parse(json);
  if (typeof xpath == 'object'){var liste = xpath.join().split(",")} else {var liste = xpath.split("|")}
  for (var i=0; i<data.games.length; i++) {
    var prov=[]
    var parts =  data.games[i].pgn.split(String.fromCharCode(10,10))
    var pparts = parts[0].split(String.fromCharCode(10))
    for (var x=0; x<pparts.length; x++){
      pparts[x]=pparts[x].replace('[','"').replace(']','').replace(' "','":"') // "key":"value"
    }
    var donnees = JSON.parse('{'+pparts.join(',')+'}') // mise au format json
    liste.forEach(function(chemin){
      prov.push(donnees.item(chemin))
    })
    if (sequence){prov.push(parts[1])}
    result.push(prov)
  }
  return result
}

/**
 * Parse a PGN file.
 *
 * @param {range} url url of PGN file
 * @param {range} xpath data to be fetched 
 * @param {boolean} sequence if true sequence will be fetched 
 * @customfunction
 */
function readPGNdirect(url,xpath,sequence) {
  var result=[]
  if (typeof xpath == 'object'){var liste = xpath.join().split(",")} else {var liste = xpath.split("|")}
  var data = UrlFetchApp.fetch(url).getContentText().split(String.fromCharCode(10,10,10))
  for (var i=0; i<data.length; i++) {
    var prov=[]
    var parts = data[i].split(String.fromCharCode(10,10))
    var pparts = parts[0].split(String.fromCharCode(10))
    for (var x=0; x<pparts.length; x++){
      pparts[x]=pparts[x].replace('[','"').replace(']','').replace(' "','":"') // "key":"value"
    }
    var donnees = JSON.parse('{'+pparts.join(',')+'}') // mise au format json
    liste.forEach(function(chemin){
      prov.push(donnees.item(chemin))
    })
    if (sequence){prov.push(parts[1])}
    result.push(prov)
  }
  return result
}

Object.prototype.item=function(i){return this[i]};
image
Rechercher des sujets similaires à "google sheets importer fichier pgn echecs"