]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/arbitools/arbitools.el
packages/arbitools.el: Removed unused variables
[gnu-emacs-elpa] / packages / arbitools / arbitools.el
index d365529a510cdc210296fc12f2cbe8d50a9e3be2..f749bfbd0c4decccb6dbb7897d9b7f0f1a17a94b 100644 (file)
@@ -3,7 +3,8 @@
 ;; Copyright 2016 Free Software Foundation, Inc.
 
 ;; Author: David Gonzalez Gandara <dggandara@member.fsf.org>
-;; Version: 0.53
+;; Version: 0.71
+;; Package-Requires: ((cl-lib "0.5"))
 
 ;; This program is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;;
 ;; - Delete player. Adjust all rank numbers - Native
 ;;
+;; - Adjust points for each player, according to results of rounds - Native
+;;
+;; - Print standings - Native
+;;
 ;; TODO:
 ;; ---------------------------------
 ;;
 ;; - Add player to team. Prompt for team and player number.
 ;;
 ;; - Generate pgn file for a round or the whole tournament.
-;; 
-;; - Adjust points for each player, according to results of rounds
 ;;
 ;; - Reorder the ranking
 ;;
 ;; - Reorder the players list
 ;;
-;; - Print Stantings
-;; 
 ;; You will find more information in www.ourenxadrez.org/arbitools.htm
 
 ;;; Code:
 
+(eval-when-compile (require 'cl-lib))
+
+(defun arbitools-prepare-feda ()
+  "Prepare file to FEDA: add carriage return at the end of lines."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (while (search-forward "\n" nil t)
+      (replace-match "\r\n"))))
 
 (defun arbitools-update (elolist)
   "Update the players ratings in a database file based on a elo list file."
 (defun arbitools-list-pairing (round)
   "Get the pairings and/or results of the given round"
   (interactive "sround: ")
-  (beginning-of-buffer)
+  (goto-char (point-min))
   (arbitools-list-players)
   (save-excursion
     (re-search-forward "^012" nil t)
              (linestring (thing-at-point 'line))
              (playerlinestring nil)
              (opponentlinestring nil)
+             opponentstring
              (rankstring (substring linestring 4 8))
              (opponent (substring linestring (+ 91 (* (- (string-to-number round) 1)10 )) 
                        (+ 95(* (- (string-to-number round) 1)10 ))))
            (insert (format "%s\n" (member "   1" paired))))
          (unless (or (member rankstring paired) (member opponent paired))
            (with-current-buffer "List of players"
-               (beginning-of-buffer)
+               (goto-char (point-min))
                (re-search-forward (concat "^" (regexp-quote  rankstring)))
                (setq playerlinestring (thing-at-point 'line))
                (setq namestring (substring playerlinestring 4 37))
-               (beginning-of-buffer)
+               (goto-char (point-min))
                (unless (or (string= opponent "0000") (string= opponent "    "))
                    (re-search-forward (concat "^" (regexp-quote opponent))))
                (setq opponentlinestring (thing-at-point 'line))
                (setq opponentstring (substring opponentlinestring 4 37))
                (when (or (string= opponent "0000")(string= opponent "    "))
                  (setq opponentstring "-"))
-               (add-to-list 'paired rankstring))
+               (cl-pushnew rankstring paired :test #'equal))
            (with-current-buffer "Pairings List"
              (cond ((string= color "w") ;; TODO: change the ranknumber with the name
                      (cond ((string= result "1")
   ;; TODO: the beautiful LaTeX
   (interactive)
   (save-excursion
-   (beginning-of-buffer)
+   (goto-char (point-min))
    (while (re-search-forward "^001" nil t)
      (let* ((linestring (thing-at-point 'line))
            (rankstring (substring linestring 5 8)))
        (with-current-buffer "List of players"
          (insert (format " %s " rankstring))))
 
-     (let* ((name (thing-at-point 'word))
-           (linestring (thing-at-point 'line))
+     (let* ((linestring (thing-at-point 'line))
            (namestring (substring linestring 14 47)))
        
        (with-current-buffer "List of players"
   ;; (insert "013 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN  0000 0000\n")
 )
 
-(defun aribitools-number-of-rounds ()
-   "Get the number of rounds in the tournament"
-   ;; FIXME: EXPERIMENTAL
-   (let ((numberofrounds 0))
+ (defun arbitools-number-of-rounds ()
+   "Get the number of rounds in the tournament. It has to be executed in the principal buffer."
+   (let* ((numberofrounds 0))
      (save-excursion
-      (beginning-of-buffer)
+      (goto-char (point-min))
       (re-search-forward "^132" nil t)
         (let* ((linestringrounds (thing-at-point 'line))
-            (actualround " ")
+            ;; (actualround " ")
             (beginning-of-round 91)
             (end-of-round 99)
             (continue t))
                     
-           (with-current-buffer "Arbitools-output" (insert (format "rounds: %s" linestringrounds)))
-           (with-current-buffer "Arbitools-output" (insert (format "length: %s" (- (length linestringrounds) 4))))
+            ;; (with-current-buffer "Arbitools-output" (insert (format "rounds: %s" linestringrounds)))
+            ;; (with-current-buffer "Arbitools-output" (insert (format "length: %s" (- (length linestringrounds) 4))))
            ;; For some reason, the length of the string is 4 characters longer than the real line
            (while continue
              (if (< end-of-round (length linestringrounds))
                 
                (progn
-                  (setq actualround (substring-no-properties linestringrounds beginning-of-round end-of-round))
+                  ;; (setq actualround (substring-no-properties linestringrounds beginning-of-round end-of-round))
                   (setq numberofrounds (+ numberofrounds 1))
                   (setq beginning-of-round (+ beginning-of-round 10))
                   (setq end-of-round (+ end-of-round 10)))
                   
-                  (setq continue nil))))))
-     (numberofrounds))
+                  (setq continue nil)))))
+     numberofrounds))
+
+(defun arbitools-calculate-points ()
+  "Automatically calculate the points of each player"
+  (interactive)
+  (save-excursion
+    (let ( (numberofrounds (arbitools-number-of-rounds))
+           (points         0.0)
+           (pointstosum    0.0)
+           (roundcount     1))
+      (goto-char (point-min))
+      (while (re-search-forward "^001" nil t)
+        (setq points 0.0)
+        (setq roundcount 1)
+        (while (<= roundcount numberofrounds)
+          (beginning-of-line)
+         (forward-char (+ 98 (* (- roundcount 1) 10))) ;; go to where the result is for each round
+          (cond ((string= (thing-at-point 'symbol) "1") (setq pointstosum 1.0))
+                ((string= (thing-at-point 'symbol) "+") (setq pointstosum 1.0))
+                ((string= (thing-at-point 'symbol) "=") (setq pointstosum 0.5))
+                ((string= (thing-at-point 'symbol) "0") (setq pointstosum 0.0))
+                ((string= (thing-at-point 'symbol) "-") (setq pointstosum 0.0))
+                ((string= (thing-at-point 'symbol) nil) (setq pointstosum 0.0)))
+          (setq points (+ points pointstosum))
+          (setq roundcount (+ roundcount 1)))
+        (beginning-of-line)
+        (forward-char 84)
+        (forward-char -3)
+        (delete-char 3)
+        (insert-char ?\s (- 3 (length (format "%s" points))))
+        (insert (format "%s" points))))))
+
+(defun arbitools-calculate-standings ()
+  "Write the standings in the Standings buffer"
+  (interactive)
+  (arbitools-calculate-points) ;; make sure the points of each player are correct
+  (save-excursion
+    (with-current-buffer "Standings"
+      (erase-buffer))
+    (let ((datachunk ""))
+      (goto-char (point-min))
+      (while (re-search-forward "^001" nil t)
+        (let* ()
+          (beginning-of-line)
+          (forward-char 89) ;; get the POS field
+          (setq datachunk (thing-at-point 'word))
+          (with-current-buffer "Standings"
+            (insert (format "%s" datachunk))
+            (insert-char ?\s (- 3 (length datachunk)))
+            (insert " "))
+          (setq datachunk (substring-no-properties (thing-at-point 'line) 14 47)) ;; get name
+          (with-current-buffer "Standings"
+            (insert (format "%s " datachunk))
+            (insert-char ?\s (- 33 (length datachunk))))
+          (beginning-of-line)
+          (forward-char 68)
+          (setq datachunk (thing-at-point 'word)) ;; get idfide 
+          (with-current-buffer "Standings"
+            (insert (format "%s " datachunk))
+            (insert-char ?\s (- 10 (length datachunk))))
+          (setq datachunk (substring-no-properties (thing-at-point 'line) 80 84)) ;; get points
+          (with-current-buffer "Standings"
+            (insert (format "%s " datachunk))
+            (insert-char ?\s (- 4 (length datachunk))))
+          (with-current-buffer "Standings"
+            (insert "\n")
+            (sort-columns 1 49 (- (point-max) 1))))))
+    (let ((newpos 0)
+          (idfide ""))
+      (goto-char (point-min))
+      (while (re-search-forward "^001" nil t)
+        (beginning-of-line)
+        (forward-char 68)
+        (setq idfide (thing-at-point 'word))
+        (with-current-buffer "Standings"
+          (goto-char (point-min))
+          (search-forward idfide nil t)
+          (setq newpos (line-number-at-pos))) ;; the POS is in the beginning of the line in Standings
+        (with-current-buffer "Arbitools-output"
+          (insert (format "%s" newpos))
+          (insert "\n"))
+        (beginning-of-line)
+        (forward-char 89) ;; go to POS field
+        (forward-char -3)
+        (delete-char 3)
+        (insert-char ?\s (- 3 (length (format "%s" newpos))))
+        (insert (format "%s" newpos))))))
 
 (defun arbitools-delete-player (player)
    "Delete a player. Adjust all the rank numbers accordingly."
          (elo            ""))
     
     (save-excursion
-      (beginning-of-buffer)
+      (goto-char (point-min))
       (re-search-forward "^132" nil t)
         (let* ((linestringrounds   (thing-at-point 'line))
-               (actualround        " ")
+               ;; (actualround        " ")
                (beginning-of-round 91)
                (end-of-round       99)
                (continue           t))
            (while continue
              (if (< end-of-round (length linestringrounds))
                (progn
-                  (setq actualround (substring-no-properties linestringrounds beginning-of-round end-of-round))
+                  ;; (setq actualround (substring-no-properties linestringrounds beginning-of-round end-of-round))
                   (setq numberofrounds (+ numberofrounds 1))
                   (setq beginning-of-round (+ beginning-of-round 10))
                   (setq end-of-round (+ end-of-round 10)))   
                (setq continue nil)))))
     (save-excursion
-     (beginning-of-buffer)
+     (goto-char (point-min))
      (while (re-search-forward "^001" nil t)
        (let* ((linestring (thing-at-point 'line))
               (rankstring (substring linestring 5 8)))
            (insert-char ?\s (- 4 (length (format "%s" (- (string-to-number rankstring) 1)))))
            (insert (format "%s" (- (string-to-number rankstring) 1)))
            (save-excursion
-             (beginning-of-buffer)
+             (goto-char (point-min))
              (while (re-search-forward "^001" nil t)
-               (let* ((linestring2         (thing-at-point 'line))
-                      (actualroundopponent (string-to-number (substring linestring2 91 94)))
-                      (roundcount          1)
-                      (testmessage         ""))
-                  (forward-char (+ 91 (* (- roundcount 1) 10)))
-                  (setq testmessage (thing-at-point 'word))
-                  (while (< roundcount numberofrounds)
+               (let* ((roundcount          1))
+                  (while (<= roundcount numberofrounds)
                     (beginning-of-line)
                     (forward-char (+ 95 (* (- roundcount 1) 10)))
                     (when (string= (format "%s" (string-to-number rankstring)) (thing-at-point 'word))
                       (delete-char 4) ;; remove the original opponent's number
                       (insert-char ?\s (- 4 (length (format "%s" (- (string-to-number rankstring) 1)))))
                       (insert (format "%s" (- (string-to-number rankstring) 1))))
-                    (setq roundcount (+ roundcount 1))))))))))
-     ;;(condition-case nil ;; TODO: fix teams info
-             ;;  (while (re-search-forward "^013")
-             ;;    (let* ((linestringteam (thing-at-point 'line)))
-             ;;      ;; go through team line and read the integrants
-             ;;      ;; when integrant equals rankstring rankstring -1
-             ;;    ))
-             ;;  (error "No teams information"))
+                    (setq roundcount (+ roundcount 1))))
+               ;;(condition-case nil ;; TODO: fix teams info
+                 (save-excursion 
+                   (while (re-search-forward "^013" nil t)
+                    (let* ((linestringteam (thing-at-point 'line))
+                          (integrantcount 0)
+                          (members 0))
+
+                        ;; to find the end of the line, the number is length -2, for some reason
+                        (setq members (/ (- (- (length linestringteam) 2) 34) 5)) ;; calculate number of members
+
+                      (while (< integrantcount members)
+                       (beginning-of-line)
+                       (forward-char (+ 40 (* (- integrantcount 1) 5)))
+                       (when (string= (format "%s" (string-to-number rankstring)) (thing-at-point 'word))
+                         (forward-char -4)
+                         (delete-char 4)
+                         (insert-char ?\s (- 4 (length (format "%s" (- (string-to-number rankstring) 1)))))
+                         (insert (format "%s" (- (string-to-number rankstring) 1))))
+                       (setq integrantcount (+ integrantcount 1))))))))))))
+             
      (save-excursion  ;; Actually delete the player's line
-       (beginning-of-buffer)
+       (goto-char (point-min))
        (while (re-search-forward "^001  DEL" nil t)
          (beginning-of-line)
          (let ((beg (point)))
      ;; TODO change number of players and number of rated players
      (save-excursion
        (with-current-buffer "Arbitools-output" (insert (format "%s" elo)))
-       (beginning-of-buffer)
+       (goto-char (point-min))
        (re-search-forward "^062 ")
        (let* ((linestring      (thing-at-point 'line))
               (numberofplayers (substring linestring 4))) 
           (insert (concat (number-to-string numberofratedplayers) "\n")))))))
 
 (defun arbitools-delete-round (round)
-   "Delete a round." ;; FIXME: it breaks when round is the last
+   "Delete a round."
    (interactive "sround: ")
    (save-excursion
-    (beginning-of-buffer)
+    (goto-char (point-min))
     (while (re-search-forward "^001" nil t)
      (forward-char (+ 88 (* (- (string-to-number round) 1) 10)))
-     (delete-char 10)
-     (insert "          "))))
+     (delete-char 8)
+     (insert "        "))))
 
 (defun arbitools-replace-empty ()
    "Replace non played games with spaces"
    (interactive)
    (save-excursion
-    (replace-string "0000 - 0" "        ")))
+    (goto-char (point-min))
+    (while (search-forward "0000 - 0" nil t)
+      (replace-match "        "))))
 
 (defun arbitools-insert-player (sex title name elo fed idfide year)
    "Insert a player"
-   ;; TODO: automatically insert the rank.
+   ;; TODO: automatically insert the player in a team
    (interactive "ssex: \nstitle: \nsname: \nselo: \nsfed: \nsidfide: \nsyear: ")
   (let ((playerlinelength nil)
         (thislinelength nil)) 
      (save-excursion
-       (beginning-of-buffer)
+       (goto-char (point-min))
        (re-search-forward "^001 ")
        (let* ((linestring (thing-at-point 'line))) 
          (setq playerlinelength (length linestring))))
-     (insert (format "001 RANK %s" sex))
-     (when (= (length sex) 0) (insert " ")) ;; add extra space if the sex string is empty
-     (insert-char ?\s (- 3 (length title)))
-     (insert (format "%s " title))
-     (insert (format "%s" name))
-     (insert-char ?\s (- 34 (length name)))
-     (insert (format "%s " elo))
-     (when (= (length elo) 0) (insert "    ")) ;; add extra space if the elo is empty
-     (when (= (length elo) 1) (insert "   ")) ;; add extra space if the elo is a "0"
-     (insert (format "%s" fed))
-     (when (= (length fed) 0) (insert "   ")) ;; add extra space if fed is empty
-     (insert-char ?\s (- 12 (length idfide)))
-     (insert (format "%s " idfide))
-     (insert (format "%s      " year))
-     (when (= (length year) 0) (insert "    ")) ;; TODO: improve this to make it support different data formats
-     (insert (format "  0.0  POS"))
-     (setq thislinelength (length (thing-at-point 'line)))
-     (insert-char ?\s (- playerlinelength thislinelength)))   
+     (save-excursion
+       (goto-char (point-min))
+       (while (re-search-forward "^001" nil t))
+       (let* ((linestring (thing-at-point 'line))
+              (rankstring (substring linestring 5 8)))
+
+         (forward-line 1)
+         (insert "\n")
+         (forward-char -1)
+         (insert (format "001 "))
+         (insert-char ?\s (- 4 (length (format "%s" (+ (string-to-number rankstring) 1)))))
+         (insert (format "%s" (+ (string-to-number rankstring) 1)))
+         (insert (format " %s" sex))
+         (when (= (length sex) 0) (insert " ")) ;; add extra space if the sex string is empty
+         (insert-char ?\s (- 3 (length title)))
+         (insert (format "%s " title))
+         (insert (format "%s" name))
+         (insert-char ?\s (- 34 (length name)))
+         (when (= (length elo) 4) (insert (format "%s " elo)))
+         (when (= (length elo) 0) (insert "     ")) ;; add extra space if the elo is empty
+         (when (= (length elo) 1) (insert "   0 ")) ;; add extra space if the elo is a "0"
+         (insert (format "%s" fed))
+         (when (= (length fed) 0) (insert "   ")) ;; add extra space if fed is empty
+         (insert-char ?\s (- 12 (length idfide)))
+         (insert (format "%s " idfide))
+         (insert (format "%s      " year))
+         (when (= (length year) 0) (insert "    ")) ;; TODO: improve this to make it support different data formats
+         (insert (format "  0.0 "))
+         (insert-char ?\s (- 4 (length (format "%s" (+ (string-to-number rankstring) 1)))))
+         (insert (format "%s" (+ (string-to-number rankstring) 1)))
+         (setq thislinelength (length (thing-at-point 'line)))
+         (insert-char ?\s (- playerlinelength thislinelength)))))   
   (save-excursion
-    (beginning-of-buffer)
+    (goto-char (point-min))
     (re-search-forward "^062 ")
     (let* ((linestring (thing-at-point 'line))
            (numberofplayers (substring linestring 4))) 
    "Insert a result."
    (interactive "sround: \nswhite: \nsblack: \nsresult: ")
    (save-excursion
-     (beginning-of-buffer)
+     (goto-char (point-min))
      (while (re-search-forward "^001" nil t)
        (forward-char 4) ;; rank number
        (when (string= white (thing-at-point 'word))
     ["New Tournament" arbitools-new-trf]
     "---"
     ["Insert Player" arbitools-insert-player]
+    ["Delete Player" arbitools-delete-player]
     ["Insert Result" arbitools-insert-result]
     ["Delete Round" arbitools-delete-round]
     "---"
     ["Update Elo" arbitools-update]
     ["Get It3 form Report" arbitools-it3]
     ["Get FEDA Rating file" arbitools-fedarating]
+    "---"
+    ["Prepare for FEDA" arbitools-prepare-feda]
     ))
 
 
   (generate-new-buffer "Arbitools-output")
   (generate-new-buffer "List of players")
   (generate-new-buffer "Pairings List")
+  (generate-new-buffer "Standings")
   (column-number-mode)
   (set (make-local-variable 'font-lock-defaults) '(arbitools-highlights)))