Escolar Documentos
Profissional Documentos
Cultura Documentos
RESUMO
Este artigo tem como objetivo descrever as funções implementados para o
processamento de arquivos PGN (Portable Game Notation) e FEN ( Forsyth-Edwards
Notation) em Haskell, utilizados normalmente para descrição de jogos de xadrez,
introduzido pelo professor Rodrigo Geraldo Ribeiro como parte das exigências da
disciplina CEA419 - Linguagens de Programação.
PALAVRAS CHAVE. PGN; FEN; Haskell; Xadrez.
ABSTRACT
This paper aims to describe the functions implemented in the development for
processment of files PGN (Portable Game Notation) and FEN ( Forsyth-Edwards
Notation) in Haskell. These files are use normally for describe the game of chess,
introduced by teacher Rodrigo Geraldo Ribeiro as part of the requirements of
discipline CEA419 – Linguagens de Programação.
KEYWORDS. PGN; FEN; Haskell; Chess.
UNIVERSIDADE FEDERAL DE OURO PRETO
1. Introdução
Haskell é uma linguagem de programação pertencente ao paradigma funcional.
Sua estrutura de controle primária são as funções. Em Haskell, uma função é um
mapeamento que leva um ou mais argumentos e produz um único resultado, e é
definida usando uma equação que dá nome à função, um nome para cada um dos seus
argumentos e um corpo que especifica como o resultado pode ser calculado em
termos dos argumentos.
Segue abaixo exemplo de função em Haskell:
A função double é uma função que recebe um inteiro como parâmetro e retorna o
dobro de seu valor, que também é um inteiro.
Programação funcional pode ser definida como um estilo de programação no qual
o método básico de computação é a aplicação de funções a argumentos. Por sua vez,
linguagem de programação funcional é aquela que se apoia no estilo funcional.
A linguagem de programação Haskell apresenta entre outras, as seguintes
características:
2. Processamento de Arquivos
Os arquivos PGN serão utilizados para que seja possível salvar o progresso do jogo
de xadrez ou para visualizar cada passo da partida descrita no formato.
Para que o processamento do arquivo ocorra precisamos saber a estrutura dos
movimentos no jogo de xadrez, onde temos uma descrição padrão denominada SAN –
Standard Algebraic Notation, um movimento pode ser regular ou especial, os regulares
são descritos por uma seqüência indicando a peça a ser movida, uma seqüência para
evitar ambigüidades entre as peças de uma mesma categoria fornecendo dados sobre
a posição inicial do movimento, é também composta por uma indicação se o
movimento resultou em uma captura, a posição do destino do movimento descrito,
informações sobre uma possível promoção de um peão e finalmente se o movimento
resultou em xeque ou xeque-mate. Existem também dois movimentos especiais
denominados “roque”, onde o rei e uma das torres são movidas simultaneamente, o
roque ao lado da rainha é especificado por O-O-O e o do lado do rei por O-O. As peças
são indicadas por letras maiúsculas de N o cavalo (Knight), B o bispo (Bishop), R a torre
(Rook), Q a rainha (Queen) e K o rei (King), na maioria das vezes as regras do jogo e a
situação do tabuleiro já determinam dada uma posição de destino qual peça esta
sendo movida, mas algumas informações sobre a posição inicial podem ser fornecida
pela coluna (file) que vai de a-h e pela linha (rank) que vai de 1-8 ou uma posição
específica do tabuleiro. A captura é denominada pela letra x e ocorre entre a
especificação de uma ambigüidade e a posição de destino, caso um peão alcance a
linha base do oponente, ele poderá ser promovido para outra peça, indicado pelo
símbolo = e a letra da peça no qual será promovido, quando o movimento resulta um
xeque ou xeque-mate é indicado pelos símbolos + ou # respectivamente.
| O-O-O
| O-O
file -> a | b | c | d | e | f | g | h
rank -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
A sintaxe dos arquivos PNG é dada pela gramática livre de contexto abaixo:
A sintaxe dos arquivos FEN é dada pela gramática livre de contexto abaixo:
whitePiece -> K | Q | B | N | R | P
blackPiece -> k | q | b | n | r | p
bar -> /
next2play -> w | b
castling -> kw qw kb pb | -
kw -> K | λ
qw -> Q | λ
kb -> k | λ
qb -> q | λ
file -> a | b | c | d | e | f | g | h
rank -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
Alguns tipos foram definidos para atender à estrutura do jogo de xadrez que foi
citado no setor 2:
data Tags
data Tag
UNIVERSIDADE FEDERAL DE OURO PRETO
tablePiece tableSmallerRoque
tableFile tableTermination
tableRank tableDots
tableCapture tableCifrer
tablePromotion tableLeftChaves
tableCheck tableRightChaves
tableBiggerRoque tableFPiece
UNIVERSIDADE FEDERAL DE OURO PRETO
tableFBar
tableFCWhiteQueen
tableFNumber
tableFCBlackKing
tableFMovesNext
tableFCBlackQueen
tableFCWhiteKing
tableFTrace
4. Parsers Implementados
<*> parseSquare
where
where
where
O parse do Square faz a união de uma coluna com uma linha, por
isso ele é dependente dos parses parsFile e parseRank, ou seja, ele
retorna uma posição completa no tabuleiro do xadrez
tipo, que será utilizada no parse onde ocorre a chamada, lembrando que
ele poderá ou não retornar o tipo capture uma vez que a string não
corresponda a esse tipo.
where
where
where
UNIVERSIDADE FEDERAL DE OURO PRETO
where
where
where
where
parseString = pack la p la
where
la = symbol '\"'
quoted = choice $ ((\_ y -> y) <$> symbol '\\' <*> char) : map
symbol "\"\\"
where
where
parseSymbol = list <$> (letter <|> digit) <*> greedy (choice $ letter :
digit : map symbol "_#=:/")
where
where
where
where
where
where
where
where
where
where
where
where
5. Funções Desenvolvidas
5.1. Main
main = do
UNIVERSIDADE FEDERAL DE OURO PRETO
Para iniciar o jogo, o usuário deverá executar o arquivo Chess que chamará a
função main, para compilar basta digitar no command do prompt: runghc <nome do
arquivo.hs> <nome do arquivo.pgn> ou digitar :main "nomedoarquvio" que o próprio
programa irá chamar as funções que processarão o arquivo.
Arquivos
GameWithComments.pgn
Simple.pgn
7. Código Fonte
• Main
• Move
• PGN
• FEN
• E a biblioteca PARSELIB
Main_________________________________________________________________
import System.Environment(getArgs)
import Data.Char
import ParseLib
import Move
UNIVERSIDADE FEDERAL DE OURO PRETO
import PGN
import FEN
main = do
Move_________________________________________________________________
import System.Environment(getArgs)
import Data.Char
import ParseLib
UNIVERSIDADE FEDERAL DE OURO PRETO
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Representação de Movimento
| MBiggerRoque BiggerRoque
| MSmallerRoque SmallerRoque
deriving(Eq, Ord)
square :: Square,
deriving(Eq, Ord)
-- Representação de "Casa"
| DRank Rank
| DSquare Square
-- Representação de Peça
| Queen
| Rook
| Bishop
| Knight
-- Representação de Fileira
data File = A
|B
|C
|D
|E
|F
|G
|H
-- Representação de Linha
| Two
| Three
| Four
| Five
| Six
| Seven
| Eight
-- Rerepsentação de Captura
-- Rerepsentação de Promoção
| PromotionKnight
| PromotionRook
| PromotionBishop
-- Representação de Check
| CheckMate
UNIVERSIDADE FEDERAL DE OURO PRETO
----------------------------------------------------------------------
----------------------------------------------------------------------
("Q", Queen),
("R", Rook),
("N", Knight),
("B", Bishop)]
("b", B),
("c", C),
("d", D),
UNIVERSIDADE FEDERAL DE OURO PRETO
("e", E),
("f", F),
("g", G),
("h", H)]
("2", Two),
("3", Three),
("4", Four),
("5", Five),
("6", Six),
("7", Seven),
("8", Eight)]
("=N", PromotionKnight),
("=R", PromotionRook),
UNIVERSIDADE FEDERAL DE OURO PRETO
("=B", PromotionBishop)]
("#", CheckMate)]
----------------------------------------------------------------------
----------------------------------------------------------------------
<*> parseSquare
where
where
where
parseDisambiguation = Just <$> (DFile <$> parseFile <|> DRank <$> parseRank <|>
DSquare <$> parseSquare)
where
where
where
where
where
----------------------------------------------------------------------
----------------------------------------------------------------------
show s ++
PGN___________________________________________________________________
import System.Environment(getArgs)
import Data.Char
import ParseLib
import Move
----------------------------------------------------------------------
----------------------------------------------------------------------
deriving(Eq, Ord)
-- Representação de Jogo
deriving(Eq, Ord)
deriving(Eq, Ord)
-- Representação de Elementos
spaces1 :: String,
move :: Move,
spaces2 :: String,
spaces3 :: String,
spaces4 :: String
-- Representação de Cifrão
-- Representação de Ponto
-- Representação de Nome
-- Representação de Valor
-- Representação de Resultado
| BlackWins
| Draw
| Unknown
-- Representação de Tags
-- Representação de Tag
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Tabela de Terminação
("0-1", BlackWins),
("1/2-1/2", Draw),
("*", Unknown)]
-- Tabela de Ponto
-- Tabela de Cifrão
----------------------------------------------------------------------
----------------------------------------------------------------------
where
where
parseTag = brackets (Tag <$> parseName <*> spaces <*> parseValue <*> spaces)
where
parseString = pack la p la
where
la = symbol '\"'
quoted = choice $ ((\_ y -> y) <$> symbol '\\' <*> char) : map symbol "\"\\"
parseSymbol = list <$> (letter <|> digit) <*> greedy (choice $ letter : digit : map symbol
"_#=:/")
where
where
where
parseNag = Nag <$> parseCifrer <*> spaces <*> parseNumber <*> spaces
parseNumber = Number <$> parseNatural <*> spaces <*> many parseDots <*> spaces
where
parseGame = Game <$> parseTags <*> spaces <*> parseMoveText <*> spaces
----------------------------------------------------------------------
----------------------------------------------------------------------
show (Value s) = s
show (Name n) = n
where
showDots [ ] = ""
show (Element numopt s1 move s2 nagopt s3 coments s4) = maybe "" show numopt
++
show s1 ++
show move ++
show s2 ++
show s3 ++
show s4
FEN___________________________________________________________________
import System.Environment(getArgs)
import Data.Char
import ParseLib
import Move
import PGN
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Representação de Peças
| WKing
| BQueen
| WQueen
| BBishop
| WBishop
| BKnight
| WKnight
| BRook
| WRook
UNIVERSIDADE FEDERAL DE OURO PRETO
| BPawn
| WPawn
| FTwo
| FThree
| FFour
| FFive
| FSix
| FSeven
| FEight
-- Representação de Barra
| FWhiteMovesNext
deriving(Eq, Ord)
-- Representação de Traço
UNIVERSIDADE FEDERAL DE OURO PRETO
-- Representação de Roque
| FCTrace FTrace
-- Representação de En Passant
| FEPTrace FTrace
{-
row1 :: FFile,
trace1 :: FTrace,
row2 :: FFile,
trace2 :: FTrace,
row3 :: FFile,
trace3 :: FTrace,
row4 :: FFile,
trace4 :: FTrace,
row5 :: FFile,
trace5 :: FTrace,
row6 :: FFile,
trace6 :: FTrace,
row7 :: FFile,
trace7 :: FTrace,
row8 :: FFile,
enpassant :: FEnPassant,
halfmove :: FHalfNumberMove,
fullmove :: FFullmoveNumber
deriving(Eq, Ord)
-}
----------------------------------------------------------------------
----------------------------------------------------------------------
UNIVERSIDADE FEDERAL DE OURO PRETO
-- Tabela de Peça
("K", WKing),
("q", BQueen),
("Q", WQueen),
("b", BBishop),
("B", WBishop),
("n", BKnight),
("N", WKnight),
("r", BRook),
("R", WRook),
("p", BPawn),
("P", WPawn)]
-- Tabela de Barra
-- Tabela de Número
("2", FTwo),
("3", FThree),
("4", FFour),
UNIVERSIDADE FEDERAL DE OURO PRETO
("5", FFive),
("6", FSix),
("7", FSeven),
("8", FEight)]
("b", FBlackMovesNext)]
-- Tabela de Traço
----------------------------------------------------------------------
----------------------------------------------------------------------
where
where
where
where
where
where
where
where
where
----------------------------------------------------------------------
----------------------------------------------------------------------
maybe
"" show bk ++
maybe ""
show bq
BIBLIOTECA PARSELIB_____________________________________________________
import Char
infixl 7 <$>
infixl 6 <*>
infixr 4 <|>
-- running a parser
run :: (Show result, Show symbol) => Parser symbol result -> [symbol] -> result
run p xs = case p xs of
((x,[]):_) -> x
-- Elementary parsers
symbol a [] = []
| otherwise = []
satisfy p [] = []
| otherwise = []
| otherwise = []
UNIVERSIDADE FEDERAL DE OURO PRETO
where n = length k
failp :: Parser s a
failp xs = []
succeed r xs = [(r,xs)]
-- Parser combinators
(p <|> q) xs = p xs ++ q xs
,( x,zs) <- q ys
|( y,ys) <- p xs
-- Auxiliary functions
determ p xs | null r = []
| otherwise = [head r]
where r = p xs
list x xs = x:xs
pi22 x y = y
pi32 x y z = y
where j x op = (x `op`)
h fs x = foldr ($) x fs
where j op x = (`op` x)
psequence [] = succeed []
8. Considerações finais
O trabalho proposto pelo professor Rodrigo Geraldo Ribeiro atingiu seu objetivo,
visto que, através dele foi adquirida uma gama de informações enormes, inclusive
sobre parser e definição de tipos de dados em Haskeel. Para desenvolver o que foi
proposto, teve-se que exercitar a manipulação de parser, entrada e saída, criação de
tipos de dados com gramáticas livres de contexto, uso de funções da biblioteca,
funções de ordem superior, estruturas de repetição e a lógica de programação em
Haskell.
9. Referência Bibliográfica