integracija2

72

Click here to load reader

Upload: ipadavic

Post on 23-Aug-2014

215 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Integracija2

SVEUĈILIŠTE U ZAGREBU

FAKULTET ORGANIZACIJE I INFORMATIKE

VARAŽDIN

Integracija logiĉkog, objektno orijentiranog programiranja i

skriptnih programskih jezika

Marko Velić

Ivan Padavić

Mentor: Prof. dr. sc. Mirko Čubrilo

Varaţdin, svibanj 2005.

Page 2: Integracija2

ii

SVEUĈILIŠTE U ZAGREBU

FAKULTET ORGANIZACIJE I INFORMATIKE

VARAŽDIN

Marko Velić, Ivan Padavić

INTEGRACIJA LOGIĈKOG, OBJEKTNO

ORIJENTIRANOG PROGRAMIRANJA I SKRIPTNIH

PROGRAMSKIH JEZIKA

Rad predloţen Fakultetu organizacije i informatike Sveučilišta u Zagrebu

povodom Natječaja za dodjelu Rektorove nagrade

Varaţdin, svibanj 2005.

Page 3: Integracija2

iii

Ovaj rad izraĎen je na Fakultetu organizacije i informatike Varaţdin, u sklopu

Natječaja za dodjelu Rektorove nagrade, pod vodstvom prof. dr. sc. Mirka Čubrila

Page 4: Integracija2

iv

Popis slika

2.1.1. PRIMJER STRUKTURE U FORMALNOJ LOGICI .................................................................... 3

2.2.1. KLAUZULA NAPISANA U PROLOGU ......................................................................................... 5

4.3.1. PSHARP.DLL, PROLOG KOD I P# INTERPRETER U ISTOM DIREKTORIJU ..................13

4.3.2.. PREVOĐENJE NAREDBOM COMPILE(). .................................................................................14

4.3.3. POTREBNE DATOTEKE UKLJUĈENE U PROJEKT ..............................................................15

4.3.4. KONAĈNI IZGLED JEDNOSTAVNE WEB APLIKACIJE “RODITELJ_DJED” .................17

4.3.5. DIJAGRAM IZRADE P# APLIKACIJE ........................................................................................17

5.2.1. KONAĈNI IZGLED C# APLIKACIJE ..........................................................................................21

5.2.2. STRUKTURNI PRIKAZ “KRIŽIĆ-KRUŽIĆ” APLIKACIJE ....................................................21

5.3.1. SUĈELJE OSTVARENO U FLASH-U ...........................................................................................24

5.3.2. STRUKTURNI PRIKAZ “KRIŽIĆ-KRUŽIĆ” APLIKACIJE NAKON INTEGRACIJE S

FLASH-OM .................................................................................................................................................25

Page 5: Integracija2

v

Sadržaj

1. UVOD ........................................................................................................................................................ 1

2. PROLOG ................................................................................................................................................... 2

2.1. LOGIČKO PROGRAMIRANJE .................................................................................................................. 2 2.2. OBILJEŢJA I SINTAKSA PROLOGA ......................................................................................................... 4

3. C# ............................................................................................................................................................... 6

3.1. .NET PLATFORMA ............................................................................................................................... 6 3.2. OBILJEŢJA C# JEZIKA ........................................................................................................................... 8

4. P# ............................................................................................................................................................... 9

4.1. SOURCE-TO-SOURCE PREVOĐENJE ....................................................................................................... 9 4.2. OBILJEŢJA P# ALATA ..........................................................................................................................11 4.3. POSTUPAK IZRADE P# APLIKACIJE – KORAK PO KORAK ......................................................................12

5. PRIMJER IZRADE CJELOVITE P# APLIKACIJE ..........................................................................18

5.1. ODABIR PROBLEMA ............................................................................................................................18 5.2. IZRADA APLIKACIJE ............................................................................................................................19 5.3. PROŠIRENJE OSNOVNE P# APLIKACIJE KORIŠTENJEM FLASH-A, ACTION SCRIPT-A I PERL-A ...............22

5.3.1. Flash grafičko sučelje ................................................................................................................22 5.3.2. Ostvarenje igre putem Interneta ................................................................................................26

6. ZAKLJUĈAK ..........................................................................................................................................28

DODATAK A – IZVORNI C# KOD WEB APLIKACIJE PRIKAZANE U POGLAVLJU 4.3. .........29

A.1. GLAVNA WEB FORMA ........................................................................................................................29 A.2. DATOTEKA DJED_2.CS .......................................................................................................................31 A.3. DATOTEKA RODITELJ_2.CS ................................................................................................................32

DODATAK B – IZVORNI PROLOG KOD IGRE “KRIŽIĆ-KRUŽIĆ” .............................................34

DODATAK C – C# IZVORNI KOD IGRE “KRIŽIĆ-KRUŽIĆ” ..........................................................38

DODATAK D - ACTION SCRIPT IZVORNI KOD GRAFIĈKOG SUĈELJA...................................52

DODATAK E - OSTVARENJE IGRE PUTEM INTERNETA ..............................................................55

E.1. ACTION SCRIPT – KLIJENTSKI DIO ......................................................................................................55 E.2. PERL – SERVERSKI DIO .......................................................................................................................60

LITERATURA ............................................................................................................................................65

Page 6: Integracija2

vi

TEMELJNA DOKUMENTACIJSKA KARTICA

Sveučilište u Zagrebu

Fakultet organizacije i informatike Varaţdin

INTEGRACIJA LOGIĈKOG, OBJEKTNO ORIJENTIRANOG

PROGRAMIRANJA I SKRIPTNIH PROGRAMSKIH JEZIKA

Marko Velić, Ivan Padavić

U ovom radu prikazane su mogućnost integracije logičkog i objektno orijentiranog

programiranja, te logičkog programiranja i skriptnih programskih jezika. U informatičkoj

industriji danas, objektni pristup izgradnji aplikacija gotovo je postao standard. Objektno

orijentirani operacijski sustavi, aplikacije, programski jezici i razvojna okruţenja nalaze se na

većini današnjih računala. Kada govorimo o rješavanju logičkih problema u programiranju,

prednost ipak ima logičko programiranje, zbog elegancije rješavanja takvih problema. Mnogi

autori danas smatraju da je Prolog vodeći jezik logičkog programiranja. Integraciju ova dva

pristupa programiranju ostvarujemo pomoću alata P#. P# spada u skupinu tzv. “source-to-source”

prevoditelja, a prevodi izvorni kod napisan u Prologu u C# izvorni kod. Na taj način moguće je

iskoristiti prednosti ovih dvaju jezika i snaţni logički mehanizam programa iz Prologa povezati s

naprednim mogućnostima jezika C#, kao što su atraktivna grafička sučelja, dobra podrška za

mreţni rad i Internet (TCP/IP) aplikacije, višedretveni rad i slično. Nakon prikaza logičkog,

objektno orijentiranog programiranja i P# alata te uputa za izgradnju aplikacije korak-po-korak,

dajemo prikaz aplikacije koju smo izgradili pomoću P#-a. Nadalje, izradili smo i jednu inačicu

programa koja koristi Flash grafičko sučelje napisano u skriptnom programskom jeziku Action

Script. Program omogućuje igru više korisnika putem Interneta realizacijom kroz programske

jezike Perl i Action Script. TakoĎer, u dodatku su priloţeni i izvorni programski kodovi razvijene

aplikacije (Prolog, C#, Action Script i Perl).

Ključne riječi: logičko programiranje, objektno orijentirano programiranje, skriptni programski

jezici, Prolog, C#, Action Script, Flash.

Mentor: prof. dr. sc. Mirko Čubrilo, redoviti profesor Fakulteta organizacije i informatike

Sveučilišta u Zagrebu

(73 stranice, 11 slika, 18 navoda literature, jezik izvornika: hrvatski)

Page 7: Integracija2

vii

BASIC DOCUMENTATION CARD

University of Zagreb

Faculty of Organization and informatics Varaţdin

INTEGRATION OF LOGIC PROGRAMMING, OBJECT ORIENTED

PROGRAMMING AND SCRIPTING PROGRAMMING LANGUAGES

Marko Velić, Ivan Padavić

In this paper we discuss how to integrate logic programming, object oriented

programming and scripting programming languages. Nowadays in software industry, object

oriented approach is de facto standard. Object oriented operation systems, applications,

programming languages and development environments can be found on most of today’s personal

computers. When it comes to solving logic problems, logic programming is often the best

approach, because of the elegant way to solve that kind of problems. Many authors say that

Prolog is the leader among logic programming languages. We implement this interoperation

using P# tool. P# belongs to a group of so called source-to-source translators. P# compiles source

code written in Prolog into C# source code. In this way, it is possible to use advantages of both

languages, and powerful logic mechanisms of Prolog language, integrate with C# advanced

features, such as attractive graphic user interfaces (GUI), network functions and support for

TCP/IP, multithreading etc. After introduction to logic, object oriented programming, P# tool and

step-by-step tutorial, we present an example of application that we developed using P#. Also we

developed one version that uses Flash GUI written with Action Script language. Program is

playable over Internet. This is accomplished by programming in Perl and Action Script. Finally,

in appendix, we included our source code (Prolog, C#, Action Script, Perl).

Kewords: logic programming, object oriented programming, scripting programming languages,

Prolog, C#, Action Script, Flash, Perl.

Supervisor: Mirko Čubrilo, Ph. D., Full Professor, Zagreb University, Faculty of Organization

and Informatics, Varaţdin

(73 pages, 11 figures, 18 references, original in: Croatian)

Page 8: Integracija2

1

1. Uvod

U programiranju danas glavnu ulogu igraju objektni pristup i objektno orijentirani

programski jezici. Moderni, objektno orijentirani programski jezici kao što su Java, C++,

C# i slični omogućuju brzu i efikasnu izgradnju aplikacija koje su vrlo štedljive u

pogledu memorijskih resursa, procesorske snage i vremena izvoĎenja. TakoĎer moderni

objektno orijentirani jezici kao C# i razvojne okoline kao Microsoft .NET uključuju

bogatu podršku za ostale postojeće tehnologije (XML, baze podataka, mreţni rad i slično)

putem svojih standardnih biblioteka. Nasuprot tome, deklarativni programski jezici za

logičko programiranje, kao što je Prolog, više su orijentirani na problem koji treba riješiti

i kako taj problem riješiti nego na izvoĎenje samog programa. Prolog i logičko

programiranje danas imaju veliku ulogu u izgradnji ekspertnih sustava, aplikacija koje

koriste inteligentno pretraţivanje baza podataka i slično. Integracijom logičkog i objektno

orijentiranog programiranja moguće je iskoristiti prednosti obaju pristupa. Integraciju ova

dva pristupa postiţemo pomoću alata P#. P# je alat koji prevodi izvorni kod Prologa u C#

izvorni kod, tzv. source-to-source prevoĎenje. Detaljniji prikaz Prologa i koncepta

logičkog programiranja dan je u poglavlju 2. Poglavlje 3 prikazuje osnove objektno

orijentiranog pristupa te daje uvid u .NET platformu i C# programski jezik. Poglavlje 4

obraĎuje P# i objašnjava postupak prevoĎenja Prolog koda u C# kod, uz demonstraciju

izrade jednostavne Web aplikacije. Poglavlje 5 detaljno opisuje izradu cijele aplikacije

“Kriţić - kruţić” čija je logika implementirana u Prologu, a grafičko sučelje u C# jeziku.

Pored source-to-source prevoĎenja, integracija različitih tehnologija moguća je

uključivanjem vanjskih programskih modula za komunikaciju meĎu dijelovima aplikacije

koji su realizirani kroz različite jezike. To smo prikazali izradom inačice koja koristi

Flash grafičko sučelje. Flash odnosno Action Script korišteni su i za realizaciju

klijentskog dijela aplikacije namijenjene za igranje putem Interneta. Server koji

omogućuje igru preko Interneta napisan je u Perl programskom jeziku. Konačno dodaci

A, B, C, D i E sadrţe izvorne programske kodove naše aplikacije.

Page 9: Integracija2

2

2. Prolog

2.1. Logičko programiranje

Pojam logičkog programiranja javlja se 1970-ih godina u radovima R. Kowalskog

i A. Colmerauera. Logičko programiranje predstavlja koncept programiranja koji se

temelji na matematičkoj logici. Programer definira odnose meĎu vrijednostima nekih

podataka te zatim postavlja upite kako bi odredio postojanje tih veza. Drugim riječima

moţemo reći i da se logičko programiranje temelji na činjenicama (premisama) iz kojih

se dobiva zaključak (konkluzija).

Niz pravila i činjenica definiranih u programu predstavlja bazu znanja iz koje se

zatim mogu donositi zaključci. Ovakav pristup programiranju najviše se upotrebljava u

izgradnji sustava temeljenih na znanju, inteligentnom pretraţivanju baza podataka i

dokazivanju matematičkih teorema gdje su se programi napisani logičkim

programiranjem pokazali brzim u donošenju zaključaka na temelju velikog broja

podataka ili činjenica koje treba razmatrati.

Kowalski - eva definicija algoritma u logičkom programiranju glasi: algoritam =

logika + kontrola. Logička komponenta predstavlja “Što se treba učiniti?”, a kontrolna

komponenta odreĎuje “Kako će se učiniti?”.

Dva temeljna pojma s kojima se susrećemo u formalnoj logici su struktura i

teorija. Strukturom nazivamo skup objekata (entiteta) zajedno sa skupom odnosa

(relacija) meĎu njima. Teorijom nazivamo skup izjavnih rečenica (iskaza) izraţenih

nekim danim jezikom. Struktura je dio svijeta koji teorijom nastojimo opisati. S druge

strane, teorijom se iskazuju neka znanja o svijetu na koji se ona odnosi. (Mario Radovan,

Programiranje u Prologu, Informator, Zagreb, 1987.)

Strukturu bismo mogli prikazati grafom, a tu strukturu opisati teorijom u obliku

rečenica. Primjer teorije su tvrdnje da je osoba “Marko” otac osobe “Ivan” i da je osoba

“Ivan” otac osobe “Stjepan”. Grafički bi struktura izgledala kako je prikazano na slici

2.1.1.

Page 10: Integracija2

3

Slika 2.1.1. Primjer strukture u formalnoj logici

Ovu strukturu mogli bismo opisati teorijom pomoću rečenica:

otac(marko, ivan).

otac(ivan, stjepan).

djed(marko, stjepan).

* Stjepan

* Ivan

otac

* Marko

otac

djed

Page 11: Integracija2

4

2.2. Obilježja i sintaksa Prologa

Jedan od najpopularnijih programskih jezika za logičko programiranje je Prolog

koji spada u skupinu tzv. deklarativnih jezika (vidi tablicu 1). Prva implementacija ovog

programskog jezika nastala je 1973. godine, a izradila ju je grupa A. Colmerauera. Prolog

je korišten za pisanje širokog spektra aplikativnih i sistemskih programa, poput

ekspertnih sustava, programa za procesiranje prirodnog jezika, prevodioca, ureĎivača

teksta i niza drugih specifičnih programa.

Naredbeni jezici Deklarativni jezici

Filozofija Korisnik točno opisuje kako

će se problem riješiti

Korisnik opisuje što je

problem

Program Niz naredbi Niz tvrdnji

Primjer Pascal, C, Java, C# Prolog, ML, Scheme, Gödel

Prednosti Brzi i specijalizirani

programi

Općeniti programi, lakše

rješavanje logičkih

problema

Tablica 2.2.1. Usporedba naredbenih i deklarativnih programskih jezika

Osnovnu komponentu u logičkom programu predstavlja predikat. Predikati se

izvršavaju uspješno ili neuspješno tj. ne vraćaju neku odreĎenu vrijednost. Prema tome u

Prologu ne postoje funkcije već atomi, termovi, predikati i klauzule.

Page 12: Integracija2

5

Hrvatski Logiĉka oznaka Prolog

i ,

ili ;

samo ako ← :-

ne \+

Tablica 2.2.2. Osnovna sintaksa Prologa

Slika 2.2.1. Klauzula napisana u Prologu

Primjer klauzule prikazan je u slici 2.2.1. Ovakva klauzula naziva se Hornova

klauzula i sastoji se od zaključka, operatora “:-” i pretpostavki. Hornove klauzule često su

temelj logike programa napisanog u Prologu. Svaka naredba tj. tvrdnja u Prologu

završava znakom “.”. Konkretno, primjer:

brat(X,Y) :− roditelj(Z,X) , roditelj(Z,Y).

tumačimo ovako:

X je brat od Y ako je Z roditelj od X-a i ako je Z roditelj od Y-a za neki Z.

Prolog u svojoj osnovi ne poznaje tipove podataka, iako su se pojavile i neke

proširene implementacije Prologa koje omogućuju tipove podataka znak (character) i

cijeli broj (integer).

predikat(x1, ..., xn) :- p1(x1, ..., xn), ..., pn(x1, ..., xm).

Glava klauzule

(zaključak)

Vrat klauzule

(kopula)

Tijelo klauzule

(pretpostavke)

Page 13: Integracija2

6

3. C#

3.1. .NET Platforma

C# je moderan objektno orijentirani programski jezik visokih performansi koji je

nastao u okviru Microsoftove .NET platforme. .NET platforma sastoji se od brojnih

tehnologija uključujući razvojna okruţenja, operacijske sustave i programske jezike. Ova

platforma uključuje napredne koncepte kao što su Garbage Collection, GAC (Global

Assembly Cache) i JIT'ing (Just In Time debugging). .NET programi prevode se u

svojevrsni meĎu-jezik (MSIL – Microsoft Intermediate Language) bez obzira koji se

.NET jezik koristi za programiranje što omogućava da više programera koji rade s

različitim jezicima, primjerice C# i VB.NET, rade na istom projektu bez prebacivanja na

jezik onog drugog. Ekvivalent MSIL-u kod Java programskog jezika je JVML (Java

Virtual Machine Language) poznat i pod nazivom Java byte-code.

Garbage Collection ili u doslovnom prijevodu “Sakupljanje smeća” označava

funkciju prevoditelja koja u programskom kodu prepoznaje objekte koji se više ne koriste

i automatski oslobaĎa memoriju, tako da programer više ne mora razmišljati o

eksplicitnom oslobaĎanju zauzetih resursa (primjerice delete naredba u C++ jeziku).

GAC ili Global Assembly Cache predstavlja dio datotečnog sustava .NET

platforme koji sluţi za pohranu dijeljenih programskih komponenti i modula. Na taj način

izbjegnuta je konfuzija koja je obično nastajala ako programer koristi puno DLL

pomoćnih datoteka za svoj program. Ova pojava znana je i pod nazivom “DLL Hell” ili

“DLL Pakao”, a temeljni problem javljao se onda kada bi različiti programeri nazivali

svoje DLL datoteke istim imenima pa bi se instalacijom jednog programa prebrisale

datoteke potrebne za rad nekog ranije instaliranog programa.

JIT'ing (Just In Time debugging) ili u slobodnom prijevodu pravovremeno

prevoĎenje koda predstavlja koncept koji omogućava prevoĎenje koda u strojni jezik

prilikom izvoĎenja aplikacije, tako da se izvršavaju samo potrebni dijelovi koda što

rezultira veoma brzim izvoĎenjem aplikacije, a dijelovi koda koji se pokreću ponovno

Page 14: Integracija2

7

nakon što su već jednom bili izvršeni ne prevode se ponovno u strojni jezik već se izvode

direktno. Samim time .NET aplikacije, kako se koriste, postaju sve brţe.

.NET platforma sadrţi i napredne koncepte za sigurnost napisanih aplikacija i

podataka koje koriste. Primjer su “meta-data” C# klase i “isolated storage” koncept. Ove

karakteristike .NET-a ograničavaju modificiranje podataka izvan okvira koje je zadao

programer. Sigurnost je poboljšana kod Web aplikacija i kod Windows aplikacija.

Page 15: Integracija2

8

3.2. Obilježja C# jezika

Otprilike svakih deset godina javlja se novi pristup programiranju. Ranih 1980-ih

pojavio se operacijski sustav Unix i programski jezik C koji je razvila tvrtka AT&T.

Početkom 1990-ih pojavio se operacijski sustav Windows i programski jezik C++. Danas

novi pristup predstavljaju .Net platforma i jezik C#. Platforma uključuje više

programskih jezika, ali C# predstavlja njen temeljni jezik. Korištenje ovog jezika

omogućuje iskorištenje svih naprednih koncepata koje pruţa objektna paradigma kao što

su: nasljeĎivanje, enkapsulacija, polimorfizam i slično. U okviru .NET platforme C# se

koristi i kao jezik za programiranje Internet aplikacija (ASP.NET).

Moţemo reći da je C# jezik naučio mnogo od svojih prethodnika tijekom protekla

tri desetljeća. U njemu već na prvi pogled prepoznajemo utjecaj programskih jezika kao

što su Java, C++, Visual Basic. Mnogi autori ističu kako je C# naslijedio eleganciju Jave

i brzinu jezika C++. C# je od Visual Basic-a naslijedio tzv. RAPID razvijanje aplikacija

koje podrazumijeva veoma brzu izradu aplikacija i jednostavno oblikovanje korisničkog

sučelja. TakoĎer C# ima dobru podršku za danas sve popularniji XML (eXtensible

Markup Language), jezik za opisivanje strukturiranih podataka. XML i C# u kombinaciji

predstavljaju vrlo dobar izbor za izradu Web aplikacija kojima je vaţno upravljanje

podacima. Takav pristup omogućava izradu dinamičkih Web stranica i predstavlja

svojevrsnu alternativu bazama podataka korištenim na Webu.

Jezik je relativno jednostavan s otprilike 80-ak ključnih riječi i podrţanim svim

standardnim tipovima podataka. Još jedna novost je i uvoĎenje foreach naredbe koja do

sada nije postojala u obitelji C jezika, a uvedena je iz Visual Basic-a. Ova naredba veoma

je korisna i cijenjena meĎu programerima jer omogućava elegantno izvršavanje naredbi

nad svim elementima polja ili bilo koje druge kolekcije podataka.

C# takoĎer podrţava i direktno pristupanje memorijskim lokacijama pomoću

pokazivača u stilu C++ jezika. Pri tom programer označava takve operacije kao unsafe i

upozorava Garbage Collection da ne oslobaĎa te lokacije dok nisu dereferencirane. To

omogućava programiranje na nešto niţoj razini.

Page 16: Integracija2

9

4. P#

4.1. Source-to-source prevođenje

Raznolikost programskih jezika, platformi i pristupa programiranju omogućava

mnogo načina rješavanja nekog problema. Ipak ponekad se javlja potreba za integracijom

različitih pristupa i tehnologija. Mogući način integracije različitih tehnologija je

uključivanje novih programskih biblioteka ili modula (plug-in) koji omogućavaju

komunikaciju meĎu programskim komponentama napisanim u različitim programskim

jezicima. Takva sučelja nazivaju se “foreign language interfaces”. Korištenje takvih

vanjskih sučelja često rezultira nepreglednim kodom koji je kasnije teţak za ispravljanje i

mijenjanje.

Drugi način je tzv. “source-to-source” prevoĎenje, a odnosi se na prevoĎenje

izvornog programskog koda napisanog u jednom programskom jeziku u programski kod

napisan u nekom drugom programskom jeziku. Obzirom da smo odabrali Prolog i C# kao

predstavnike područja iz kojih dolaze, a zbog njihovih prednosti opisanih ranije, u ovom

radu odlučili smo integraciju logičkog i objektno orijentiranog programiranja ostvariti

alatom P#. Naime, uz sve nabrojane prednosti i napredne koncepte, .NET i C# nemaju

podršku za čisto logičko programiranje.

Tablica 4.1.1. Primjeri “source-to-source” prevoditelja

Prevoditelj Polazni kod Ciljni kod

Jython Phython JVML

GNU Prolog Prolog C

Prolog Café Prolog Java

P# Prolog C#

Page 17: Integracija2

10

U narednom poglavlju prikazat ćemo cjelovit primjer P# aplikacije koju smo

izradili. Osim “source-to-source” prevoĎenja, u jednom od naših primjera prikazali smo i

drugu mogućnost integracije različitih tehnologija koja se temelji na korištenju vanjskih

sučelja izradom druge verzije programa, koja predstavlja svojevrsno proširenje prve

verzije, te uz P# koristi “Flash” grafičko sučelje, napisano u Action Script skriptnom

programskom jeziku te mogućnost igre preko Interneta putem Action Script i Perl

skriptnih jezika.

Page 18: Integracija2

11

4.2. Obilježja P# alata

Prednosti Prologa i C#-a navedene u poglavljima 2 i 3, mogu se iskoristiti

integracijom obaju jezika, a to postiţemo pomoću alata P#. Alat P# razvijen je na

Sveučilištu u Edinburghu pod vodstvom Johnatana J. Cook-a. P# spada u skupinu tzv.

“source-to-source” prevoditelja tj. programa koji izvorni programski kod napisan u

jednom programskom jeziku prevode u izvorni programski kod nekog drugog jezika.

Kako se iz samog imena moţe naslutiti, P# integrira Prolog i C#. P# prevoditelj baziran

je na Prolog Cafe - u, ranije razvijenom prevoditelju Prolog koda u Java izvorni kod. P#

radi na taj način da klauzule napisane u prologu izdvaja u posebne datoteke s ekstenzijom

.cs (ekstenzija datoteka napisanih u jeziku C#). Temeljna komponenta P#-a je Psharp.dll

datoteka koja se moţe uključiti u GAC, a dovoljno je i da se nalazi u istom direktoriju

kao i prevoditelj (interpreter), da bi prevoĎenje bilo uspješno. Nakon prevoĎenja .pl

(.pro) datoteke (.pl i .pro su ekstenzije datoteka napisanih u Prologu, treba obratiti paţnju

na .pl ekstenziju koja je ujedno i ekstenzija datoteka Perl programskog jezika) u niz C#

datoteka, programer te datoteke moţe uključiti u svoj projekt unutar razvojne okoline te

nakon uključivanja Psharp.dll datoteke (ukoliko nije uključena u GAC) moţe slobodno

pozivati funkcije iz .cs datoteka te na taj način koristiti predikate i činjenice definirane u

Prologu. Detaljan opis ovog postupka slijedi uz jednostavan primjer.

Page 19: Integracija2

12

4.3. Postupak izrade P# aplikacije – korak po korak

Za potrebe demonstriranja postupka prevoĎenja Prologa u C# ovdje ćemo

prikazati jednostavan primjer Internet aplikacije. Za početak, napisali smo jednostavan

program u Prologu koji glasi ovako:

djed(X,Z) :- roditelj(X,Y), roditelj(Y,Z).

roditelj(marko, ivan).

roditelj(ivan, stjepan).

U programskom kodu imamo klauzulu koja opisuje tipičan problem tranzitivnosti.

U klauzuli tvrdimo sljedeće: osoba X je djed osobe Y ako i samo ako je osoba X roditelj

osobe Y i ako je osoba Y roditelj osobe Z. Nadalje u kodu imamo dvije činjenice koje

govore da je osoba “marko” roditelj osobe “ivan”, a osoba “ivan” roditelj osobe

“stjepan”. Mogli bismo reći da u ovom jednostavnom primjeru početna klauzula

predstavlja naš mehanizam zaključivanja, a činjenice jednostavnu bazu znanja. Dakle ako

bismo ovom programu postavili pitanje tko je roditelj osobe “stjepan”, odgovor bi trebao

biti “ivan”, što proizlazi iz druge činjenice, a ukoliko bismo ga pitali tko je djed osobe

“stjepan”, na temelju obaju činjenica i naše klauzule, odgovor bi trebao biti “marko”.

Slijedi opis postupka izgradnje Web aplikacije na temelju ovog Prolog programa.

Na početku, potrebno je datoteku s programskim kodom koji ţelimo prevesti, staviti u isti

direktorij sa P# interpreterom i Psharp.dll datotekom (ukoliko ona nije u GAC-u) što je i

prikazano na slici 4.3.1.

Page 20: Integracija2

13

Slika 4.3.1. Psharp.dll, Prolog kod i P# interpreter u istom direktoriju

Zatim je potrebno pokrenuti interpreter i naredbom compile(). prevesti ţeljeni kod

u C#. Unutar zagrada navodimo ime datoteke. Rezultat će biti dvije C# datoteke u istom

direktoriju. Nazivi datoteka odgovaraju nazivima klauzule i činjenica. Datoteka

Djed_2.cs sadrţi logiku klauzule, a datoteka Roditelj_2 sadrţi podatke o roditeljima.

Postupak je prikazan na slici 4.3.2.

Page 21: Integracija2

14

Slika 4.3.2.. Prevođenje naredbom compile().

Sljedeći korak je uključivanje datoteka u projekt unutar razvojne okoline, što je

prikazano na slici 4.3.3. Opet, ukoliko Psharp.dll nije unutar GAC-a, potrebno ga je

referencirati unutar projekta. Sada programer u svojoj glavnoj formi moţe pozivati

dodane C# datoteke.

Za pozivanje funkcija iz datoteka potrebno je definirati novo sučelje naredbama:

PrologInterface sharp = new PrologInterface( );

sharp.AddAssembly (System.Reflection.Assembly.GetExecutingAssembly());

Potrebno je stvoriti novi term koji će biti simbol (atom) naredbom:

SymbolTerm s1 = SymbolTerm.MakeSymbol( TextBox1.Text );

Poziv predikata ostvarujemo sljedećim naredbama:

sharp.SetPredicate( new Djed_2(netko, s1,new ReturnCs( sharp ) ) );

sharp.Call();

Page 22: Integracija2

15

Slika 4.3.3. Potrebne datoteke uključene u projekt

Slijedi popis P# funkcija za stvaranje novih termova u drugim tipovima podataka.

Za cijele brojeve: IntegerTerm i = new IntegerTerm( 3 );

Za decimalne brojeve: DoubleTerm d = new DoubleTerm( 2.5 );

Za stvaranje C# objekta kao npr. StringBuilder, koristimo: CsObjectTerm o = new CsObjectTerm( new StringBuilder( ) );

Za stvaranje varijable: VariableTerm v = new VariableTerm( );

Ako P# Prolog kod instancira varijablu v, nakon što je učinjen poziv Prologa, v moţe biti

dereferencirana kako bi se pribavila vrijednost iz Prologa, primjerice: IntegerTerm it = (IntegerTerm)( v.Dereference() );

Ako ţelimo stvoriti jednostavnu listu [1,x,2], moţemo koristiti kod: ListTerm empty = SymbolTerm.MakeSymbol( "[]" );

ListTerm item1 = new IntegerTerm( 1 );

ListTerm item2 = SymbolTerm.MakeSymbol( "x" );

Page 23: Integracija2

16

ListTerm item3 = new IntegerTerm( 2 );

ListTerm list = new ListTerm( item1,

new ListTerm( item2,

new ListTerm( item3, empty )

)

);

ako ţelimo definirati strukturu podataka dob ('Josip',25), programski kod bi bio:

Term[] args = { SymbolTerm.MakeSymbol( "Josip" ),

new IntegerTerm( 25 ) };

StructureTerm st = new StructureTerm(

SymbolTerm.MakeSymbol( "dob", 2 ), // ( ime strukture, broj

članova strukture )

args );

C# programski kod glavne forme koja poziva generirane C# datoteke nalazi se u

dodatku A. Pritiskom na tipku “Tko je djed?” pozivamo Prolog predikat stvarajući novi

term koji je simbol, a prima vrijednost polja u koje se unosi ime osobe. Predikat to ima

prima kao parametar i vraća ime osobe koja je traţeni djed. Sličan je postupak i za tipku

“Tko je roditelj?”. Konačni izgled aplikacije prikazan je na slici 4.3.4.

Page 24: Integracija2

17

Slika 4.3.4. Konačni izgled jednostavne Web aplikacije “Roditelj_djed”

Ovaj primjer veoma je jednostavan ali reprezentativan u pogledu postupka

izgradnje P# aplikacije. Za potrebe ovog rada izgradili smo primjer cjelovite, sloţenije

aplikacije, a njen detaljan prikaz dan je u sljedećem poglavlju.

Slika 4.3.5. Dijagram izrade P# aplikacije

Prolog

izvorni kod

P#

prevoditelj C# izvorni

kod C#

prevoditelj Izvršna

datoteka

Page 25: Integracija2

18

5. Primjer izrade cjelovite P# aplikacije

5.1. Odabir problema

Prilikom odabira problema koji smo ţeljeli riješiti, a kako bismo prikazali moć

P#-a i općenito integracije logičkog i objektnog programiranja, vaţno je bilo da primjer

bude relativno jednostavan, a da uključuje sve bitne mogućnosti P# alata. Na temelju

ovih pretpostavki zaključili smo da bi bilo najučinkovitije izraditi primjer jednostavne

logičke igrice čiji bismo kod napisan u Prologu, a zaduţen za logiku igre, pomoću P#-a

integrirali s C#-om i ostvarili aplikaciju koja će imati C# grafičko sučelje. Implementirali

smo jednostavnu logičku igricu “Kriţić-kruţić” koja ima ploču formata 4*4. Pravila igre

nalaţu da se igrači izmjenjuju nakon svakog poteza i pobjednik je onaj igrač koji prvi

sloţi četiri simbola vodoravno, okomito ili dijagonalno na ploči. Obično, ako su oba

igrača paţljiva, igra završava bez pobjednika sa svim popunjenim poljima. Igra je

izvedena kao program koji će se pokretati na lokalnom računalu korisnika.

Page 26: Integracija2

19

5.2. Izrada aplikacije

Logika igre napisana je u Prologu i temelji se na tri osnovna pravila koje računalo

razmatra prije nego odigra potez. Prvo pravilo računalu nalaţe da, ukoliko postoji

mogućnost da korisnik pobjedi tj. da mu nedostaje još jedan simbol u nizu, blokira tu

mogućnost postavljanjem svog simbola na to polje. Drugo pravilo nalaţe računalu da

odigra pobjednički potez, ako je moguć, tj. ako računalo ima tri simbola u nizu negdje na

ploči. Treće pravilo izvršava se ako ne postoje uvjeti za prva dva pravila, a pomoću njega

se računa najbolji potez koji bi u budućnosti mogao stvoriti izglednu situaciju za pobjedu.

Grafičko sučelje ostvareno je u C#-u na način da šesnaest gumbića predstavlja ploču na

kojoj se igra. Kruţići i kriţići ispisuju se na gumbićima, nakon što igrač odigra neki

potez. Pritisak na gumbić poziva C# funkciju koja pozadini aplikacije (koja je prevedena

iz Prologa) šalje trenutno stanje ploče. Ako korisnik igra protiv računala, logika iz

Prologa na temelju spomenutih pravila odreĎuje sljedeći potez. To je izvedeno

pozivanjem Prolog predikata iza C#-a. Trenutno stanje ploče predstavlja parametar za

predikat na temelju kojeg slijedi zaključivanje.

Nakon što je program napisan u Prologu preveden u C# postupkom opisanim u

poglavlju 4.3. komunikacija grafičkog sučelja i Prologa ostvarena je funkcijama u

glavnoj formi programa. Slijedi kratak prikaz nekih vaţnijih funkcija, a u dodatku je

priloţen i cijeli programski kod.

Funkcija za korisnikov potez:

private void korisnik(int broj)

{

PrologInterface sharp = new PrologInterface( );

Term a1 = new IntegerTerm( broj );

Term a2 = new VariableTerm( );

Predicate humanMove = new PlayInGivenPlace_4( currentPlayer,

currentBoard,a2, a1, new ReturnCs( sharp ) );

sharp.SetPredicate( humanMove );

sharp.Call( );

Term result = a2.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length() != 16 )

{

labela.Text="invalid";

return;

}

currentBoard = a2.Dereference();

Term elm;

Page 27: Integracija2

20

elm = ((ListTerm)result).cdr.Dereference();

SwapPlayer();

DrawBoard( (ListTerm)currentBoard );

CheckForWinningLine();

}

Funkcija za potez računala:

private void ComputerMove( )

{

PrologInterface sharp = new PrologInterface( );

Term a3 = new VariableTerm( );

Predicate compMove = new Rule_3( currentPlayer, currentBoard,

a3, new ReturnCs( sharp ) );

sharp.SetPredicate( compMove );

sharp.Call( );

Term result = a3.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length() != 16 )

{

return;

}

currentBoard = a3.Dereference();

SwapPlayer( );

Term elm2;

elm2 = ((ListTerm)result).cdr.Dereference();

DrawBoard( (ListTerm)currentBoard );

CheckForWinningLine( );

}

Funkcija za provjeru pobjede:

private void CheckForWinningLine( )

{

PrologInterface sharp = new PrologInterface( );

Term a2 = new VariableTerm( );

Predicate win = new WinningLine_2( currentBoard, a2,

new ReturnCs( sharp ) );

sharp.SetPredicate( win );

sharp.Call( );

Term result = a2.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length() != 16 )

{

return;

}

DrawWin( (ListTerm)result );

}

Funkcija za osvjeţavanje ploče:

private void resetiraj()

{

VariableTerm ispis = new VariableTerm();

PrologInterface sharp = new PrologInterface( );

sharp.AddAssembly

(System.Reflection.Assembly.GetExecutingAssembly());

Term a1 = new VariableTerm( );

Predicate reset = new Blank_1( a1, new ReturnCs( sharp ) );

sharp.SetPredicate( reset );

sharp.Call( );

Term result = a1.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length() != 16 )

Page 28: Integracija2

21

{

labela.Text = "Invalid result!";

return;

}

Term elm;

elm = ((ListTerm)result).cdr.Dereference();

currentBoard = result.Dereference();

DrawBoard( (ListTerm)currentBoard );

for (int i = 0; i < 16; i++)

{

if (Cellovi[i].Text != "")

{

Cellovi[ i ].Text = "";

}

}

}

Slika 5.2.1. Konačni izgled C# aplikacije

Slika 5.2.2. Strukturni prikaz “Križić-kružić” aplikacije

Prolog Logička

komponenta

Korisničko sučelje C#

P#

Page 29: Integracija2

22

5.3. Proširenje osnovne P# aplikacije korištenjem Flash-a, Action

Script-a i Perl-a

5.3.1. Flash grafičko sučelje

Osnovna zamisao ovoga dijela rada bila je demonstracija drugog načina

povezivanja različitih tehnologija, a to je uključivanje programskih modula koji

omogućavaju razmjenu informacija meĎu različitim programskim jezicima. Izradili smo

primjer koji povrh P# aplikacije koristi i Flash za još atraktivniji prikaz grafičkog sučelja.

Danas je čest slučaj da se programi napisani u objektnim jezicima kao C# ili C++

povezuju s Flash komponentama baš iz ovog razloga. Time je omogućeno integriranje

multimedijalnih rješenja s logikom iz Prologa, dodavanje animacija, zvučnih efekata i

slično. Općenito o Flash-u moţemo reći da donosi moćan sustav za izradu multimedijskih

sadrţaja. Uz Flash koristi se programski jezik Action Script koji omogućava manipulaciju

multimedijskim sadrţajem i programiranje kompleksnih interaktivnih sustava. Flash i

Action Script prvenstveno su namijenjeni za Web, ali kao što vidimo moguća je i izrada

sloţenih Windows aplikacija, bilo samo kroz Flash ili integracijom s drugim

tehnologijama kao što je to ovdje slučaj. Programski moduli koji omogućuju pozivanje

Flash-a iz C#-a su sljedeći: AxShockwaveFlashObjects.dll i ShockwaveFlashObjects.dll.

Deklaracija i funkcije koje se pozivaju unutar koda i omogućuju interakciju C#

programa i Flash sučelja su sljedeće:

private AxShockwaveFlashObjects.AxShockwaveFlash axShockwaveFlash1;

this.axShockwaveFlash1 = new AxShockwaveFlashObjects.AxShockwaveFlash();

((System.ComponentModel.ISupportInitialize)(this.axShockwaveFlash1)).BeginInit();

((System.ComponentModel.ISupportInitialize)(this.axShockwaveFlash1)).EndInit();

this.axShockwaveFlash1.Enabled = true;

this.axShockwaveFlash1.Location = new System.Drawing.Point(0, 0);

this.axShockwaveFlash1.Name = "axShockwaveFlash1";

this.axShockwaveFlash1.OcxState =

((System.Windows.Forms.AxHost.State)(resources.GetObject("axShockwaveFlash1.OcxState")));

this.axShockwaveFlash1.Size = new System.Drawing.Size(800, 600);

this.axShockwaveFlash1.TabIndex = 24;

this.Controls.Add(this.axShockwaveFlash1);

private void Form1_Load(object sender, System.EventArgs e)

{

Form1 ova_forma = new Form1();

Page 30: Integracija2

23

bool neistina = false;

this.Show();

Pocetak forma = new Pocetak();

forma.ShowDialog();

forma.Activate();

Cellovi = new Button[] {Cells1, Cells2, Cells3, Cells4, Cells5,

Cells6, Cells7, Cells8,

Cells9, Cells10, Cells11, Cells12, Cells13, Cells14, Cells15, Cells16 };

resetiraj();

}

private void axShockwaveFlash1_FSCommand(object sender,

AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e)

{

int proba;

if (e.command == "flashMessage")

{

this.richTextBox1.AppendText(e.args + "\n");

proba = Convert.ToInt32(e.args);

korisnik(proba);

}

if (e.command == "resetiraj")

{

resetiraj();

}

}

private string posalji_pobjedu (string ploca)

{ richTextBox1.Text+=ploca;

string posalji = "";

int brojac = 0;;

for (int i = 1; i<=31; i=i+2)

{ brojac++;

if (ploca[i].ToString() != "," &&

ploca[i].ToString() != "b" && ploca[i].ToString() != "[" && ploca[i].ToString() != "]")

posalji +=brojac.ToString()+"|";

}

this.axShockwaveFlash1.SetVariable("pobjeda", posalji);

richTextBox1.Text += posalji;

richTextBox1.Text += currentPlayer.ToString();

return "s";

}

private void ComputerMove( )

{

if (mod_igre.Equals(1))

{

PrologInterface sharp = new PrologInterface( );

Term a3 = new VariableTerm( );

Predicate compMove = new Rule_3( currentPlayer,

currentBoard,

a3, new ReturnCs( sharp ) );

sharp.SetPredicate( compMove );

sharp.Call( );

Term result = a3.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length() != 16

)

{

return;

Page 31: Integracija2

24

}

this.axShockwaveFlash1.SetVariable("varijabla",

parsiraj(currentBoard.ToString(),a3.Dereference().ToString()).ToString());

currentBoard = a3.Dereference();

labela.Text = a3.Dereference().ToString();

Term elm2;

elm2 = ((ListTerm)result).cdr;

DrawBoard( (ListTerm)currentBoard );

CheckForWinningLine( );

SwapPlayer();

}

}

Cjeloviti izvorni kod priloţen je u dodatku zajedno s Action Script kodom koji se

odvija iza grafičkog sučelja.

Slika 5.3.1. Sučelje ostvareno u Flash-u

Page 32: Integracija2

25

Slika 5.3.2. Strukturni prikaz “Križić-kružić” aplikacije nakon integracije s Flash-om

Prolog Logička

komponenta

Korisničko sučelje C#

P#

Flash

Page 33: Integracija2

26

5.3.2. Ostvarenje igre putem Interneta

U današnjoj softverskoj industriji sve je tanja linija koja odjeljuje “desktop” od

Internet aplikacija. Čest je slučaj da klijent traţi aplikaciju koja će u sebi imati integrirane

obje mogućnosti, bilo za poslovne ili neke druge namjene. Kada govorimo o Internet

aplikacijama najznačajnija i danas najčešće korištena je klijent-server arhitektura.

Općenito klijent server arhitektura je mreţna arhitektura u kojoj postoje dvije

vrste računala odnosno aplikacija. Server ili posluţitelj svoje usluge nudi ostalim

entitetima koji sudjeluju u komunikaciji bilo da su oni drugi serveri ili klijenti. Klijent

predstavlja entitet koji koristi usluge servera. U današnjim sustavima se te uloge često

izmjenjuju. Klijent-server arhitektura se razvila kao odgovor na krutu arhitekturu

terminala i main-frame računala kao i na ubrzani razvitak karakteristika osobnih računala.

Klijent-server arhitekturu koristili smo i u našem primjeru. Klijent je ostvaren

pomoću jezika Action Script, a posluţitelj je ostvaren u skriptnom programskom jeziku

Perl. Komunikacija izmeĎu klijenta i servera ostvarena je priključnicom (socket-om).

Server otvara priključnicu i čeka konekciju klijenta. Priključnica je ostvarena parom host-

port, gdje host odreĎuje računalo, a port priključnu točku. Isječak koda koji ostvaruje

priključnicu je:

# $lsn - socket prikljucnica servera postavljena na slusanje

$lsn = new IO::Socket::INET(Listen => 1,LocalPort => 7777, Reuse

=> 1, Proto => 'tcp' ) or die ("Nisam se uspio pokrenuti: $!");

$lsn->blocking(0);

$lsn->autoflush(1);

warn "Server je podignut...\n";

Klijentska strana ostvarena je u Action Script jeziku, a na zadanu priključnicu povezuje

se sljedećom funkcijom:

function spoji(){

socket = new XMLSocket();// Stvara se novi XMLSocket objekt

socket.connect(host,port);// Konekcija na server

Sada kad je veza uspostavljena, mogu se razmjenjivati poruke. Slijedi primjer.

Page 34: Integracija2

27

Klijentska strana:

function trazi_listu(){

var zalistu = "303" //303 kod trazenje liste

saljem = new XML(zalistu);

socket.send(saljem);

}

Ovom funkcijom klijent od servera traţi listu trenutno spojenih korisnika.

Serverska strana:

sub saljilistu {

my $nw, $key, $val;

my $count = 0;

my $msg = "503 ";

while (($key, $val) = each %users){

if ($count == 0) {

$msg .= $val->{UNAME};

} else {

$msg .= "|" . $val->{UNAME};

}

$count++;

} #while

$msg .= $terminator;

$nw = syswrite($users{$client}->{SOCKREF}, $msg, length($msg));

warn "Poslana lista korisniku: " . $users{$client}->{UNAME} . "

($nw bytes)\n";

}

Server na zahtjev klijenta vraća zatraţenu listu trenutno spojenih korisnika.

Cijela aplikacija ostvarena je nizom takvih komunikacija izmeĎu klijenta i servera,

cjeloviti programski kod priloţen je u dodatku.

Web adresa na kojoj se moţe pronaći Web inačica je http://student.foi.hr/~ipadavic.

Page 35: Integracija2

28

6. Zaključak

Pokušali smo dati prikaz integracije logičkog i objektno orijentiranog

programiranja pomoću alata P#. Logičko programiranje je način rješavanja specifičnih

problema primjenom matematičke logike. Najpoznatiji jezik logičkog programiranja je

Prolog. Prolog se upotrebljava u izradi ekspertnih sustava, naprednom pretraţivanju baza

podataka, procesiranju prirodnog jezika i slično. Danas je u informatičkoj industriji

najznačajniji objektni pristup programiranju. Dobar primjer objektnog programskog

jezika je C#. C# jezik omogućava korištenje svih koncepata objektnog pristupa

(nasljeĎivanje, polimorfizam, enkapsulacija i sl.). P# omogućava pisanje aplikacija koje

koriste logiku iz Prologa i moderne mogućnosti C#-a kao što su grafička sučelja, mreţni

rad, višedretveni rad, korištenje mnoštva postojećih biblioteka (primjerice za XML, baze

podataka i sl.) ili povezivanje s drugim postojećim tehnologijama putem vanjskih sučelja.

Opisali smo postupak izgradnje P# aplikacije korak-po-korak na primjeru jednostavne

Web aplikacije. TakoĎer izradili smo cjelovitu aplikaciju “Kriţić-kruţić” u dvije verzije,

prvoj koja korisničko sučelje implementira u C#-u i drugoj koja C# koristi kao poveznicu

izmeĎu logike iz Prologa i atraktivnog grafičkog sučelja izraĎenog u Flash-u i

omogućava igru putem Interneta. Igra putem interneta ostvarena je pomoću Action

Script-a za klijentsku stranu i Perl-a za serversku stranu.

Page 36: Integracija2

29

Dodatak A – Izvorni C# kod Web aplikacije prikazane u

poglavlju 4.3.

A.1. Glavna Web forma

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using JJC.Psharp.Lang;

using JJC.Psharp.Predicates;

using JJC.Psharp.Lang.Resource;

using JJC.Psharp.Resources;

namespace Roditelj_djed_web

{

public class WebForm1 : System.Web.UI.Page

{

protected System.Web.UI.WebControls.TextBox TextBox1;

protected System.Web.UI.WebControls.Button Button1;

protected System.Web.UI.WebControls.Label Label1;

protected System.Web.UI.WebControls.Label Label2;

protected System.Web.UI.WebControls.Button Button2;

protected System.Web.UI.WebControls.Label Label3;

protected System.Web.UI.WebControls.TextBox TextBox3;

protected System.Web.UI.WebControls.TextBox TextBox2;

private void Page_Load(object sender, System.EventArgs e)

{

}

#region Web Form Designer generated code

override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}

private void InitializeComponent()

{

Page 37: Integracija2

30

this.Button1.Click += new

System.EventHandler(this.Button1_Click);

this.Button2.Click += new

System.EventHandler(this.Button2_Click);

this.Load += new System.EventHandler(this.Page_Load);

}

#endregion

private void Button1_Click(object sender, System.EventArgs

e)

{

PrologInterface sharp = new PrologInterface( );

sharp.AddAssembly

(System.Reflection.Assembly.GetExecutingAssembly());

SymbolTerm s1 = SymbolTerm.MakeSymbol( TextBox1.Text

);

VariableTerm netko = new VariableTerm( );

sharp.SetPredicate( new Djed_2(

netko,

s1,

new ReturnCs( sharp ) ) );

sharp.Call();

TextBox2.Text += netko.Dereference().ToString()+" " ;

}

private void Button2_Click(object sender, System.EventArgs

e)

{

PrologInterface sharp = new PrologInterface( );

sharp.AddAssembly

(System.Reflection.Assembly.GetExecutingAssembly());

SymbolTerm s1 = SymbolTerm.MakeSymbol( TextBox1.Text

);

VariableTerm netko = new VariableTerm( );

sharp.SetPredicate( new Roditelj_2(

netko,

s1,

new ReturnCs( sharp ) ) );

sharp.Call();

TextBox3.Text += netko.Dereference().ToString()+" " ;

}

}

}

Page 38: Integracija2

31

A.2. Datoteka Djed_2.cs

namespace JJC.Psharp.Predicates {

using JJC.Psharp.Lang;

using JJC.Psharp.Lang.Resource;

using Predicates = JJC.Psharp.Predicates;

using Resources = JJC.Psharp.Resources;

public class Djed_2 : Predicate {

public Term arg1, arg2;

public Djed_2(Term a1, Term a2, Predicate cont) {

arg1 = a1;

arg2 = a2;

this.cont = cont;

}

public Djed_2(){}

public override void setArgument(Term[] args, Predicate cont) {

arg1 = args[0];

arg2 = args[1];

this.cont = cont;

}

public override Predicate exec( Prolog engine ) {

engine.setB0();

Term a1, a2, a3;

Predicate p1;

a1 = arg1.Dereference();

a2 = arg2.Dereference();

a3 = engine.makeVariable();

p1 = new Predicates.Roditelj_2(a3, a2, cont);

return new Predicates.Roditelj_2(a1, a3, p1);

}

public override int arity() { return 2; }

public override string ToString() {

return "djed(" + arg1 + ", " + arg2 + ")";

}

}

}

Page 39: Integracija2

32

A.3. Datoteka Roditelj_2.cs

namespace JJC.Psharp.Predicates {

using JJC.Psharp.Lang;

using JJC.Psharp.Lang.Resource;

using Predicates = JJC.Psharp.Predicates;

using Resources = JJC.Psharp.Resources;

public class Roditelj_2 : Predicate {

static internal readonly Predicate dollar_fail_0 = new

Predicates.dollar_fail_0();

static internal readonly Predicate Roditelj_2_1 = new

Predicates.Roditelj_2_1();

static internal readonly Predicate Roditelj_2_2 = new

Predicates.Roditelj_2_2();

static internal readonly Predicate Roditelj_2_var = new

Predicates.Roditelj_2_var();

public Term arg1, arg2;

public Roditelj_2(Term a1, Term a2, Predicate cont) {

arg1 = a1;

arg2 = a2;

this.cont = cont;

}

public Roditelj_2(){}

public override void setArgument(Term[] args, Predicate cont) {

arg1 = args[0];

arg2 = args[1];

this.cont = cont;

}

public override Predicate exec( Prolog engine ) {

engine.aregs[1] = arg1;

engine.aregs[2] = arg2;

engine.cont = cont;

return call( engine );

}

public virtual Predicate call( Prolog engine ) {

engine.setB0();

return engine.switch_on_term(

Roditelj_2_var,

dollar_fail_0,

Roditelj_2_var,

dollar_fail_0,

dollar_fail_0

);

}

public override int arity() { return 2; }

Page 40: Integracija2

33

public override string ToString() {

return "roditelj(" + arg1 + ", " + arg2 + ")";

}

}

sealed class Roditelj_2_var : Roditelj_2 {

static internal readonly Predicate Roditelj_2_var_1 = new

Predicates.Roditelj_2_var_1();

public override Predicate exec( Prolog engine ) {

return engine.jtry(Roditelj_2_1, Roditelj_2_var_1);

}

}

sealed class Roditelj_2_var_1 : Roditelj_2 {

public override Predicate exec( Prolog engine ) {

return engine.trust(Roditelj_2_2);

}

}

sealed class Roditelj_2_1 : Roditelj_2 {

static internal readonly SymbolTerm s1 =

SymbolTerm.MakeSymbol("marko");

static internal readonly SymbolTerm s2 =

SymbolTerm.MakeSymbol("ivan");

public override Predicate exec( Prolog engine ) {

Term a1, a2;

a1 = engine.aregs[1].Dereference();

a2 = engine.aregs[2].Dereference();

Predicate cont = engine.cont;

if ( !s1.Unify(a1, engine.trail) ) return engine.fail();

if ( !s2.Unify(a2, engine.trail) ) return engine.fail();

return cont;

}

}

sealed class Roditelj_2_2 : Roditelj_2 {

static internal readonly SymbolTerm s1 =

SymbolTerm.MakeSymbol("ivan");

static internal readonly SymbolTerm s2 =

SymbolTerm.MakeSymbol("stjepan");

public override Predicate exec( Prolog engine ) {

Term a1, a2;

a1 = engine.aregs[1].Dereference();

a2 = engine.aregs[2].Dereference();

Predicate cont = engine.cont;

if ( !s1.Unify(a1, engine.trail) ) return engine.fail();

if ( !s2.Unify(a2, engine.trail) ) return engine.fail();

return cont;

}

}

}

Page 41: Integracija2

34

Dodatak B – Izvorni Prolog kod igre “Križić-kružić”

% igra krizic-kruzic (prema J.J. Cook, University of Edinburgh,

% http://www.dcs.ed.ac.uk/home/jjc/psharp/psharp-1.1/dlpsharp.html)

:- discontiguous( rule/3 ).

:- dynamic( sumvec/1 ).

:- dynamic( current/1 ).

:- dynamic( x_won/0 ).

:- dynamic( o_won/0 ).

blank( [b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b] ).

% vodoravno

row( [o, o, o, o, b, b, b, b, b, b, b, b, b, b, b, b] ).

row( [b, b, b, b, o, o, o, o, b, b, b, b, b, b, b, b] ).

row( [b, b, b, b, b, b, b, b, o, o, o, o, b, b, b, b] ).

row( [b, b, b, b, b, b, b, b, b, b, b, b, o, o, o, o] ).

% okomito

row( [o, b, b, b, o, b, b, b, o, b, b, b, o, b, b, b] ).

row( [b, o, b, b, b, o, b, b, b, o, b, b, b, o, b, b] ).

row( [b, b, o, b, b, b, o, b, b, b, o, b, b, b, o, b] ).

row( [b, b, b, o, b, b, b, o, b, b, b, o, b, b, b, o] ).

% dijagonalno

row( [o, b, b, b, b, o, b, b, b, b, o, b, b, b, b, o] ).

row( [b, b, b, o, b, b, o, b, b, o, b, b, o, b, b, b] ).

% npr.

current( [o, o, b, x, x, b, b, b, b] ).

%

pickoutrow( [], [], [] ) :- !.

pickoutrow( [o|Rt], [Ch|Ct], [Ch|A] ) :- !, pickoutrow( Rt, Ct, A ).

pickoutrow( [b|Rt], [Ch|Ct], A ) :- !, pickoutrow( Rt, Ct, A ).

count_symb_inner( [], A, A, S ).

count_symb_inner( [S|T], A, R, S ) :- !, A1 is A + 1, count_symb_inner(

T, A1, R, S ).

count_symb_inner( [_|T], A, R, S ) :- count_symb_inner( T, A, R, S ).

count_symb( L, R, S ) :- count_symb_inner( L, 0, R, S ).

add_in_blank( Sym, [], [], [] ).

add_in_blank( Sym, [o|Rt], [b|B], [Sym|B2] ) :- !, add_in_blank( Sym,

Rt, B, B2 ).

add_in_blank( Sym, [_|Rt], [H|B], [H|B2] ) :- add_in_blank( Sym, Rt, B

, B2 ).

% OSTVARIVANJE POBJEDE (tu ce uvijek vratiti kruzic)

% ----------------------------------------------

Page 42: Integracija2

35

winning_line( Board, Line ) :-

row( R ), pickoutrow( R, Board, PR ),

( count_symb( PR, 4, o ) ; count_symb( PR, 4, x ) ), !,

Line = R.

% PRAVILO 1 (racunalo je o).

% ------

opposer( o, x ).

opposer( x, o ).

rule( Player, Board, NewBoard ) :-

row( R ), pickoutrow( R, Board, PR ),

count_symb( PR, 3, Player ), count_symb( PR, 1, b ), !,

add_in_blank( Player, R, Board, NewBoard ),

( Player = x -> asserta( x_won ) ; asserta( o_won ) ).

%PRAVILO 2

% ------

rule( Player, Board, NewBoard ) :-

row( R ), pickoutrow( R, Board, PR ),

opposer( Player, Opposer ),

count_symb( PR, 3, Opposer ), count_symb( PR, 1, b ), !,

add_in_blank( Player, R, Board, NewBoard ).

% PRAVILO 3

% ------

add_lists( [], [], [] ).

add_lists( [Ah|At], [Bh|Bt], [Sh|St] ) :- Sh is Ah + Bh, add_lists( At,

Bt, St ).

blank_at_pos_inner( [], P ) :- fail.

blank_at_pos_inner( [b|Rt], P, P ) :- !.

blank_at_pos_inner( [_|Rt], P, P ) :- fail.

blank_at_pos_inner( [_|Rt], P, C ) :- C1 is C + 1, blank_at_pos_inner(

Rt, P, C1 ).

blank_at_pos( R, P ) :- blank_at_pos_inner( R, P, 1 ).

row_contains_inner( [Rh|Rt], P, P ) :- !, Rh = o.

row_contains_inner( [Rh|Rt], P, Q ) :- Q1 is Q + 1, row_contains_inner(

Rt, P, Q1 ).

row_contains( R, P ) :- row_contains_inner( R, P, 1 ).

construct_scores_inner( Player, R, B, [], 17 ) :- !.

construct_scores_inner( Player, R, B, [1|St], P ) :-

blank_at_pos( B, P ), row_contains( R, P ), pickoutrow( R, B, PR ),

count_symb( PR, 4, b ), !,

P1 is P + 1, construct_scores_inner( Player, R, B, St, P1 ).

construct_scores_inner( Player, R, B, [2|St], P ) :-

blank_at_pos( B, P ), row_contains( R, P ), pickoutrow( R, B, PR ),

count_symb( PR, 3, b ), count_symb( PR, 1, Player ), !,

P1 is P + 1, construct_scores_inner( Player, R, B, St, P1 ).

construct_scores_inner( Player, R, B, [8|St], P ) :-

blank_at_pos( B, P ), row_contains( R, P ), pickoutrow( R, B, PR ),

Page 43: Integracija2

36

count_symb( PR, 2, b ), count_symb( PR, 2, Player ), !,

P1 is P + 1, construct_scores_inner( Player, R, B, St, P1 ).

construct_scores_inner( Player, R, B, [0|St], P ) :-

P1 is P + 1, construct_scores_inner( Player, R, B, St, P1 ).

construct_scores_2( P, B ) :- row( R ), construct_scores_inner( P, R,

B, S, 1 ),

sumvec( SUM ), add_lists( SUM, S, New ), abolish( sumvec/1 ),

asserta( sumvec( New ) ), fail.

construct_scores_2( P, B ) :- true.

construct_scores( P, B, S ) :- abolish( sumvec/1 ),

asserta( sumvec( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0] ) ), !,

construct_scores_2( P, B ), sumvec( S ).

max_list_inner( [], M, M ).

max_list_inner( [H|T], N, M ) :- H > N, !, max_list_inner( T, H, M ).

max_list_inner( [H|T], N, M ) :- max_list_inner( T, N, M ).

max_list( [H|T], M ) :- max_list_inner( [H|T], H, M ).

play_in_first_max( P, [], [], M, [] ) :- !, M = -1.

play_in_first_max( P, [b|Bt], [M|St], M, [P|NBt] ) :- !,

play_in_first_max( P, Bt, St, -1, NBt ).

play_in_first_max( P, [Bh|Bt], [_|St], M, [Bh|NBt] ) :-

play_in_first_max( P, Bt, St, M, NBt ).

rule( Player, Board, NewBoard ) :-

construct_scores( Player, Board, Scores ), max_list( Scores, Max ),

play_in_first_max( Player, Board, Scores, Max, NewBoard ).

play_in_given_place_inner( P, [], [], Pos, A ) :- !, Pos = -1.

play_in_given_place_inner( P, [b|Bt], [P|St], Pos, Pos ) :-

!, A1 is Pos + 1, play_in_given_place_inner( P, Bt, St, -1, A1 ).

play_in_given_place_inner( P, [Bh|Bt], [Bh|St], Pos, A ) :-

A1 is A + 1, play_in_given_place_inner( P, Bt, St, Pos, A1 ).

play_in_given_place( Player, Board, NewBoard, Position ) :-

play_in_given_place_inner( Player, Board, NewBoard, Position, 1 ).

play_me_inner :-

current( B ),

rule( o, B, B2 ),

write( B2 ), nl,

write( 'Play where? ' ), read( Pos ),

play_in_given_place( x, B2, B3, Pos ),

write( B3 ), nl,

abolish( current/1 ),

asserta( current( B3 ) ),

play_me_inner.

play_me :-

abolish( current/1 ), blank( B ), asserta( current( B ) ),

play_me_inner.

Page 44: Integracija2

37

play_self_inner :-

current( B ),

rule( o, B, B2 ),

write( B2 ), nl,

rule( x, B2, B3 ),

write( B3 ), nl,

abolish( current/1 ),

asserta( current( B3 ) ),

play_self_inner.

play_self :-

abolish( current/1 ), blank( B ), asserta( current( B ) ),

play_self_inner.

% sucelje za pamcenje stanja

% ---------------------------

reset_board( B ) :- abolish( current/1 ), blank( B ), asserta( current(

B ) ), abolish( x_won/0 ), abolish( o_won/0 ).

human_x_move( Position, NewBoard ) :- current( B ),

play_in_given_place( x, B, NewBoard, Position ),

abolish( current/1 ), asserta( current( NewBoard ) ).

computer_move( NewBoard ) :- current( B ), rule( o, B, NewBoard ),

abolish( current/1 ), asserta( current( NewBoard ) ).

% POTEZ RACUNALA

% ---------------

% PRAVILO 1: ako u ovom pokusaju mozes pobijediti, ucini tako.

% PRAVILO 2: ako drugi igrac moze pobijediti u iducem potezu, blokiraj

ga.

% PRAVILO 3: sada za svako moguce polje,

% count 1 za mogucu pobjedu koja jos nije pocela.

% count 2 za mogucu pobjedu ako je jedno polje vec zauzeto.

Page 45: Integracija2

38

Dodatak C – C# izvorni kod igre “Križić-kružić”

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.IO;

using JJC.Psharp.Lang;

using JJC.Psharp.Predicates;

using JJC.Psharp.Lang.Resource;

using JJC.Psharp.Resources;

namespace ox4_pado

{

public class Form1 : System.Windows.Forms.Form

{

public static int nacin_igre;

public static bool kontrolna=false;

private System.ComponentModel.Container components = null;

private System.Windows.Forms.Button Cells1;

private System.Windows.Forms.Button Cells2;

private System.Windows.Forms.Button Cells6;

private System.Windows.Forms.Button Cells7;

private System.Windows.Forms.Button Cells5;

private System.Windows.Forms.Button Cells8;

private System.Windows.Forms.Button Cells4;

private System.Windows.Forms.Button Cells3;

private System.Windows.Forms.Button Cells11;

private System.Windows.Forms.Button Cells12;

private System.Windows.Forms.Button Cells16;

private System.Windows.Forms.Button Cells13;

private System.Windows.Forms.Button Cells15;

private System.Windows.Forms.Button Cells14;

private System.Windows.Forms.Button Cells10;

private System.Windows.Forms.Button Cells9;

public SymbolTerm currentPlayer =

SymbolTerm.MakeSymbol("o");

public Term currentBoard;

private System.Windows.Forms.MainMenu mainMenu1;

private System.Windows.Forms.MenuItem menuItem1;

private System.Windows.Forms.MenuItem menuItem2;

private System.Windows.Forms.MenuItem menuItem3;

private System.Windows.Forms.MenuItem menuItem4;

private System.Windows.Forms.MenuItem menuItem5;

private System.Windows.Forms.MenuItem menuItem6;

private System.Windows.Forms.Button[] Cellovi;

Page 46: Integracija2

39

public Form1()

{

InitializeComponent();

}

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

private void InitializeComponent()

{

this.Cells1 = new System.Windows.Forms.Button();

this.Cells2 = new System.Windows.Forms.Button();

this.Cells6 = new System.Windows.Forms.Button();

this.Cells7 = new System.Windows.Forms.Button();

this.Cells5 = new System.Windows.Forms.Button();

this.Cells8 = new System.Windows.Forms.Button();

this.Cells4 = new System.Windows.Forms.Button();

this.Cells3 = new System.Windows.Forms.Button();

this.Cells11 = new System.Windows.Forms.Button();

this.Cells12 = new System.Windows.Forms.Button();

this.Cells16 = new System.Windows.Forms.Button();

this.Cells13 = new System.Windows.Forms.Button();

this.Cells15 = new System.Windows.Forms.Button();

this.Cells14 = new System.Windows.Forms.Button();

this.Cells10 = new System.Windows.Forms.Button();

this.Cells9 = new System.Windows.Forms.Button();

this.mainMenu1 = new System.Windows.Forms.MainMenu();

this.menuItem1 = new System.Windows.Forms.MenuItem();

this.menuItem3 = new System.Windows.Forms.MenuItem();

this.menuItem2 = new System.Windows.Forms.MenuItem();

this.menuItem4 = new System.Windows.Forms.MenuItem();

this.menuItem5 = new System.Windows.Forms.MenuItem();

this.menuItem6 = new System.Windows.Forms.MenuItem();

this.SuspendLayout();

//

// Cells1

//

Page 47: Integracija2

40

this.Cells1.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells1.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells1.Location = new System.Drawing.Point(40,

40);

this.Cells1.Name = "Cells1";

this.Cells1.Size = new System.Drawing.Size(72, 48);

this.Cells1.TabIndex = 5;

this.Cells1.Click += new

System.EventHandler(this.Cells1_Click);

//

// Cells2

//

this.Cells2.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells2.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells2.Location = new System.Drawing.Point(128,

40);

this.Cells2.Name = "Cells2";

this.Cells2.Size = new System.Drawing.Size(75, 48);

this.Cells2.TabIndex = 6;

this.Cells2.Click += new

System.EventHandler(this.Cells2_Click);

//

// Cells6

//

this.Cells6.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells6.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells6.Location = new System.Drawing.Point(128,

104);

this.Cells6.Name = "Cells6";

this.Cells6.Size = new System.Drawing.Size(75, 48);

this.Cells6.TabIndex = 7;

this.Cells6.Click += new

System.EventHandler(this.Cells6_Click);

//

// Cells7

//

this.Cells7.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells7.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells7.Location = new System.Drawing.Point(216,

104);

this.Cells7.Name = "Cells7";

this.Cells7.Size = new System.Drawing.Size(75, 48);

this.Cells7.TabIndex = 10;

this.Cells7.Click += new

System.EventHandler(this.Cells7_Click);

Page 48: Integracija2

41

//

// Cells5

//

this.Cells5.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells5.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells5.Location = new System.Drawing.Point(40,

104);

this.Cells5.Name = "Cells5";

this.Cells5.Size = new System.Drawing.Size(75, 48);

this.Cells5.TabIndex = 11;

this.Cells5.Click += new

System.EventHandler(this.Cells5_Click);

//

// Cells8

//

this.Cells8.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells8.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells8.Location = new System.Drawing.Point(304,

104);

this.Cells8.Name = "Cells8";

this.Cells8.Size = new System.Drawing.Size(75, 48);

this.Cells8.TabIndex = 13;

this.Cells8.Click += new

System.EventHandler(this.Cells8_Click);

//

// Cells4

//

this.Cells4.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells4.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells4.Location = new System.Drawing.Point(304,

40);

this.Cells4.Name = "Cells4";

this.Cells4.Size = new System.Drawing.Size(75, 48);

this.Cells4.TabIndex = 14;

this.Cells4.Click += new

System.EventHandler(this.Cells4_Click);

//

// Cells3

//

this.Cells3.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells3.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells3.Location = new System.Drawing.Point(216,

40);

this.Cells3.Name = "Cells3";

this.Cells3.Size = new System.Drawing.Size(75, 48);

Page 49: Integracija2

42

this.Cells3.TabIndex = 15;

this.Cells3.Click += new

System.EventHandler(this.Cells3_Click);

//

// Cells11

//

this.Cells11.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells11.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells11.Location = new System.Drawing.Point(216,

160);

this.Cells11.Name = "Cells11";

this.Cells11.Size = new System.Drawing.Size(75, 48);

this.Cells11.TabIndex = 23;

this.Cells11.Click += new

System.EventHandler(this.Cells11_Click);

//

// Cells12

//

this.Cells12.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells12.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells12.Location = new System.Drawing.Point(304,

160);

this.Cells12.Name = "Cells12";

this.Cells12.Size = new System.Drawing.Size(75, 48);

this.Cells12.TabIndex = 22;

this.Cells12.Click += new

System.EventHandler(this.Cells12_Click);

//

// Cells16

//

this.Cells16.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells16.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells16.Location = new System.Drawing.Point(304,

224);

this.Cells16.Name = "Cells16";

this.Cells16.Size = new System.Drawing.Size(75, 48);

this.Cells16.TabIndex = 21;

this.Cells16.Click += new

System.EventHandler(this.Cells16_Click);

//

// Cells13

//

this.Cells13.Cursor =

System.Windows.Forms.Cursors.Hand;

Page 50: Integracija2

43

this.Cells13.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells13.Location = new System.Drawing.Point(40,

224);

this.Cells13.Name = "Cells13";

this.Cells13.Size = new System.Drawing.Size(75, 48);

this.Cells13.TabIndex = 20;

this.Cells13.Click += new

System.EventHandler(this.Cells13_Click);

//

// Cells15

//

this.Cells15.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells15.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells15.Location = new System.Drawing.Point(216,

224);

this.Cells15.Name = "Cells15";

this.Cells15.Size = new System.Drawing.Size(75, 48);

this.Cells15.TabIndex = 19;

this.Cells15.Click += new

System.EventHandler(this.Cells15_Click);

//

// Cells14

//

this.Cells14.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells14.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells14.Location = new System.Drawing.Point(128,

224);

this.Cells14.Name = "Cells14";

this.Cells14.Size = new System.Drawing.Size(75, 48);

this.Cells14.TabIndex = 18;

this.Cells14.Click += new

System.EventHandler(this.Cells14_Click);

//

// Cells10

//

this.Cells10.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells10.Font = new

System.Drawing.Font("Microsoft Sans Serif", 20F,

System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,

((System.Byte)(238)));

this.Cells10.Location = new System.Drawing.Point(128,

160);

this.Cells10.Name = "Cells10";

this.Cells10.Size = new System.Drawing.Size(75, 48);

this.Cells10.TabIndex = 17;

Page 51: Integracija2

44

this.Cells10.Click += new

System.EventHandler(this.Cells10_Click);

//

// Cells9

//

this.Cells9.Cursor =

System.Windows.Forms.Cursors.Hand;

this.Cells9.Font = new System.Drawing.Font("Microsoft

Sans Serif", 20F, System.Drawing.FontStyle.Regular,

System.Drawing.GraphicsUnit.Point, ((System.Byte)(238)));

this.Cells9.Location = new System.Drawing.Point(40,

160);

this.Cells9.Name = "Cells9";

this.Cells9.Size = new System.Drawing.Size(72, 48);

this.Cells9.TabIndex = 16;

this.Cells9.Click += new

System.EventHandler(this.Cells9_Click);

//

// mainMenu1

//

this.mainMenu1.MenuItems.AddRange(new

System.Windows.Forms.MenuItem[] {

this.menuItem1,

this.menuItem6});

//

// menuItem1

//

this.menuItem1.Index = 0;

this.menuItem1.MenuItems.AddRange(new

System.Windows.Forms.MenuItem[] {

this.menuItem3,

this.menuItem2,

this.menuItem4,

this.menuItem5});

this.menuItem1.Text = "&Igra";

//

// menuItem3

//

this.menuItem3.Index = 0;

this.menuItem3.Text = "&Nova Igra";

this.menuItem3.Click += new

System.EventHandler(this.menuItem3_Click);

//

// menuItem2

//

this.menuItem2.Index = 1;

this.menuItem2.Text = "&Osvježi ploču";

this.menuItem2.Click += new

System.EventHandler(this.menuItem2_Click);

Page 52: Integracija2

45

//

// menuItem4

//

this.menuItem4.Index = 2;

this.menuItem4.Text = "-";

//

// menuItem5

//

this.menuItem5.Index = 3;

this.menuItem5.Text = "I&zlaz";

this.menuItem5.Click += new

System.EventHandler(this.menuItem5_Click);

//

// menuItem6

//

this.menuItem6.Index = 1;

this.menuItem6.Text = "Pomoć";

this.menuItem6.Click += new

System.EventHandler(this.menuItem6_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5,

13);

this.ClientSize = new System.Drawing.Size(414, 304);

this.Controls.Add(this.Cells11);

this.Controls.Add(this.Cells12);

this.Controls.Add(this.Cells16);

this.Controls.Add(this.Cells13);

this.Controls.Add(this.Cells15);

this.Controls.Add(this.Cells14);

this.Controls.Add(this.Cells10);

this.Controls.Add(this.Cells9);

this.Controls.Add(this.Cells3);

this.Controls.Add(this.Cells4);

this.Controls.Add(this.Cells8);

this.Controls.Add(this.Cells5);

this.Controls.Add(this.Cells7);

this.Controls.Add(this.Cells6);

this.Controls.Add(this.Cells2);

this.Controls.Add(this.Cells1);

this.FormBorderStyle =

System.Windows.Forms.FormBorderStyle.Fixed3D;

this.Menu = this.mainMenu1;

this.Name = "Form1";

this.StartPosition =

System.Windows.Forms.FormStartPosition.CenterScreen;

this.Text = "Križić - kružić";

this.Load += new

System.EventHandler(this.Form1_Load);

this.ResumeLayout(false);

}

#endregion

[STAThread]

Page 53: Integracija2

46

static void Main()

{

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs

e)

{

resetiraj();

}

private void korisnik(int broj)

{

PrologInterface sharp = new PrologInterface( );

Term a1 = new IntegerTerm( broj );

Term a2 = new VariableTerm( );

Predicate humanMove = new PlayInGivenPlace_4(

currentPlayer, currentBoard,

a2, a1, new ReturnCs( sharp ) );

sharp.SetPredicate( humanMove );

sharp.Call( );

Term result = a2.Dereference();

currentBoard = a2.Dereference();

Term elm;

elm = ((ListTerm)result).cdr.Dereference();

DrawBoard( (ListTerm)currentBoard );

CheckForWinningLine();

SwapPlayer();

if (kontrolna==false)

ComputerMove();

}

private void CheckForWinningLine( )

{

PrologInterface sharp = new PrologInterface( );

Term a2 = new VariableTerm( );

Predicate win = new WinningLine_2( currentBoard, a2,

new ReturnCs( sharp ) );

sharp.SetPredicate( win );

sharp.Call( );

Term result = a2.Dereference();

if ( !result.IsList() || ((ListTerm)result).Length()

!= 16 )

{

return;

Page 54: Integracija2

47

}

DrawWin( (ListTerm)result );

kontrolna = true;

}

private void DrawWin( ListTerm newBoard )

{

Term result = newBoard;

int brojac=0;

string ploca=result.ToString();

for (int i=1;i<=31;i=i+2)

{

if (ploca[i].ToString() != "b" &&

ploca[i].ToString() != "," && ploca[i].ToString() != "[" &&

ploca[i].ToString() !="]")

{

Cellovi[ brojac ].BackColor =

Color.Beige;

}

brojac++;

}

int gumb=0;

for (gumb=0; gumb<16; gumb++)

Cellovi[gumb].Enabled=false;

System.Windows.Forms.MessageBox.Show("Pobjeda igrača

"+currentPlayer.ToString()+" !");

}

private void SwapPlayer( )

{

if (currentPlayer.name.Equals("x"))

{

currentPlayer = SymbolTerm.MakeSymbol( "o" );

}

else

{

currentPlayer = SymbolTerm.MakeSymbol( "x" );

}

}

private void ComputerMove( )

{

if (nacin_igre == 1)

{

PrologInterface sharp = new PrologInterface( );

Term a3 = new VariableTerm( );

Predicate compMove = new Rule_3( currentPlayer,

currentBoard,

Page 55: Integracija2

48

a3, new ReturnCs( sharp ) );

sharp.SetPredicate( compMove );

sharp.Call( );

Term result = a3.Dereference();

if ( !result.IsList() ||

((ListTerm)result).Length() != 16 )

{

return;

}

currentBoard = a3.Dereference();

Term elm2;

elm2 = ((ListTerm)result).cdr.Dereference();

DrawBoard( (ListTerm)currentBoard );

CheckForWinningLine( );

SwapPlayer( );

}

}

private void button3_Click(object sender, System.EventArgs

e)

{

ComputerMove();

}

public void postavi (int vrijednost, bool logika)

{

nacin_igre=vrijednost;

kontrolna = logika;

}

private void Form1_Load(object sender, System.EventArgs e)

{

this.Show();

Pocetak p = new Pocetak( );

p.ShowDialog();

Cellovi = new Button[] {Cells1, Cells2, Cells3,

Cells4, Cells5, Cells6, Cells7, Cells8,

Cells9, Cells10, Cells11, Cells12, Cells13, Cells14, Cells15,

Cells16 };

resetiraj();

}

private void resetiraj()

{

kontrolna = false;

Page 56: Integracija2

49

currentPlayer = SymbolTerm.MakeSymbol( "o" );

VariableTerm ispis = new VariableTerm();

PrologInterface sharp = new PrologInterface( );

sharp.AddAssembly

(System.Reflection.Assembly.GetExecutingAssembly());

Term a1 = new VariableTerm( );

Predicate reset = new Blank_1( a1, new ReturnCs(

sharp ) );

sharp.SetPredicate( reset );

sharp.Call( );

Term result = a1.Dereference();

Term elm;

elm = ((ListTerm)result).cdr.Dereference();

currentBoard = result.Dereference();

DrawBoard( (ListTerm)currentBoard );

for (int i = 0; i < 16; i++)

{

if (Cellovi[i].Text != "")

{

Cellovi[ i ].Text = "";

}

}

int brojac=0;

string ploca=result.ToString();

for (int i=1;i<=31;i=i+2)

{

Cellovi[ brojac ].BackColor = Color.LightGray;

brojac++;

}

int gumb=0;

for (gumb=0; gumb<16; gumb++)

Cellovi[gumb].Enabled=true;

}

private void DrawBoard( ListTerm newBoard )

{

Term result = newBoard;

Term elm;

for (int i = 0; i < 16; i++)

{

elm = ((ListTerm)result).car.Dereference();

if (elm.ToString() != "b")

{

Cellovi[ i ].Text = elm.ToString();

}

result =

((ListTerm)result).cdr.Dereference();

Page 57: Integracija2

50

if( !( result is ListTerm ) )

break;

}

}

private void CelloviClick(object sender, System.EventArgs

e)

{

int cell = -1;

for( int i = 1; i <= 16; ++i )

{

if( Cellovi[ i - 1 ] == sender )

cell = i;

}

if( cell == -1 )

return;

korisnik(cell);

}

private void Cells1_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells2_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells3_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells4_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells5_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells6_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells7_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells8_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells9_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells10_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells11_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells12_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells13_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells14_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells15_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void Cells16_Click(object sender, System.EventArgs

e) { CelloviClick( sender, e ); }

private void menuItem2_Click(object sender,

System.EventArgs e)

{

Page 58: Integracija2

51

resetiraj();

}

private void menuItem3_Click(object sender,

System.EventArgs e)

{

Pocetak p = new Pocetak();

p.ShowDialog();

resetiraj();

}

private void menuItem5_Click(object sender,

System.EventArgs e)

{

this.Close();

}

private void menuItem6_Click(object sender,

System.EventArgs e)

{

Form1 neka = new Form1();

string put = Directory.GetCurrentDirectory();

Help.ShowHelp(neka, @put + "\\neki.htm","Help");

}

}

}

Page 59: Integracija2

52

Dodatak D - Action Script izvorni kod grafičkog sučelja

_root.pocetni = "o";

_root.trenutni = _root.pocetni;

_root.kursoro._visible = false;

_root.kursorx._visible = false;

_root.pobjeda2 = null;

_root.pobjeda = null;

_root.watch("varijabla",function(id,oldval,newval)

{

varijabla2 = newval;

if (varijabla2 ne "reset"){

_root.petlja.gotoAndPlay(2);

_root.onemoguciklik();

//postavi(varijabla2,"komp");

}

else

{

resetiraj();

}

});

_root.watch("pobjeda",function(id,oldval,newval){

pobjeda2 = newval;

_root.petlja2.gotoAndPlay(2);

});

/////////////////////////////////////////////////////////////////

function postavi (broj,tko){

if (_root.trenutni eq "o"){

duplicateMovieClip(_root.ploca.krug,"krug"+broj,1000-broj);

novi = _root.ploca["krug"+broj];

gumb = _root.ploca["btn"+broj];

}

if (_root.trenutni eq "x"){

duplicateMovieClip(_root.ploca.xic,"xic"+broj,1000-broj);

novi = _root.ploca["xic"+broj];

gumb = _root.ploca["btn"+broj];

}

_root.zamjena_igraca();

novi._x = gumb._x+70;

novi._y = gumb._y+45;

gumb.enabled = false;

novi._visible = true;

novi.start();

_root.mySound.start("", 1);

if (tko ne "komp"){

fscommand("flashMessage", broj);

Page 60: Integracija2

53

}

//trace (broj);

//trace (novi);

//trace (gumb);

}

function zamjena_igraca(){

if (_root.trenutni eq "x")

_root.trenutni = "o";

else

_root.trenutni = "x";

}

function resetiraj(){

for (i=1; i<=16; i++){

brisix = _root.ploca["xic"+i];

brisio = _root.ploca["krug"+i];

gumbic = _root.ploca["btn"+i];

if (brisix ne "undefined"){

brisix.removeMovieClip();

gumbic.enabled = true;

}

if (brisio ne "undefined"){

brisio.removeMovieClip();

gumbic.enabled = true;

}

}

}

/////////////////////////////////////////// ZVUKOVI

mySound = new Sound();

mySound.attachSound("Ping");

/////////////////////////////////////////////

_root.onMouseMove = function(){

_root.kursoro._x = _root._xmouse;

_root.kursoro._y = _root._ymouse;

_root.kursorx._x = _root._xmouse;

_root.kursorx._y = _root._ymouse;

}

/////////////////////////////////////////////

function onemoguciklik(){

for (i=1; i<=16; i++){

gumbic = _root.ploca["btn"+i];

gumbic.enabled = false;

}

}

//////////////////////////////////////////////

function omoguciklik(){

for (i=1; i<=16; i++){

gumbic = _root.ploca["btn"+i];

brisix = _root.ploca["xic"+i];

brisio = _root.ploca["krug"+i];

if ((brisio eq "undefined") && (brisix eq "undefined")){

gumbic.enabled = true;

Page 61: Integracija2

54

}

}

}

function oznaci_pobjedu(kod_dilimiter){

onemoguciklik();

polje_pobjede = kod_dilimiter.split("|");

if(_root.trenutni eq "o"){

prvi = _root.ploca["xic"+polje_pobjede[0]];

drugi = _root.ploca["xic"+polje_pobjede[1]];

treci = _root.ploca["xic"+polje_pobjede[2]];

cetvrti = _root.ploca["xic"+polje_pobjede[3]];

}

else

{

prvi = _root.ploca["krug"+polje_pobjede[0]];

drugi = _root.ploca["krug"+polje_pobjede[1]];

treci = _root.ploca["krug"+polje_pobjede[2]];

cetvrti = _root.ploca["krug"+polje_pobjede[3]];

}

pobjeda2 = prvi;

prvi.gotoAndStop(13);

drugi.gotoAndStop(13);

treci.gotoAndStop(13);

cetvrti.gotoAndStop(13);

_root.ploca.obrub._visible = false;

_root.kursoro._visible = false;

_root.kursorx._visible = false;

Mouse.show();

}

Page 62: Integracija2

55

Dodatak E - Ostvarenje igre putem Interneta

E.1. Action Script – klijentski dio

//------globalne varijable--------------------------------------

niz = new Array();

var otvoreni=0;

var zastava=0;

var globalna;

var privatna = 0;

var tkosamja;

var komesaljem="svima";

var skroll = 0;

//--------------------------------------------------------------

function login_ok(arg){

var nadimak = arg;

var stanje = "Uspješno ste logirani!";

_root.login.unos.fade.stanje = stanje;

_root.login.unos.fade.prolaz = 1;

trazi_listu();

}

function login_err(broj){

if (broj eq "2"){

var stanje = "Nepostojeće korisničko ime!";

_root.login.unos.fade.stanje = stanje;

}

if (broj eq "3"){

var stanje = "Upisali ste krivu zaporku!";

_root.login.unos.fade.stanje = stanje;

}

if (broj eq "4"){

var stanje = "Korisnik je već prijavljen!";

_root.login.unos.fade.stanje = stanje;

}

}

function provjeri_liniju(linija){

kod = linija.substr(0,3);

if (kod eq "500"){

odgovor = linija.substr(4,length(linija)-4);

niz = odgovor.split("|");

_root.tkosamja = niz[0];

if (niz[1] eq "1"){login_ok(niz[0]);}

if (niz[1] eq "2"){login_err(2);}

if (niz[1] eq "3"){login_err(3);}

if (niz[1] eq "4"){login_err(4);}

}

Page 63: Integracija2

56

if (kod eq "503"){

odgovor = linija.substr (4,length(linija)-4);

niz = odgovor.split("|");

sortiraj_niz();

}

if (kod eq "504"){

odgovor = linija.substr (4,length(linija)-4);

dodaj_na_listu(odgovor);

}

if (kod eq "505"){

odgovor = linija.substr (4,length(linija)-4);

makni_sa_liste(odgovor);

makni_tab(odgovor);

}

if (kod eq "501"){

odgovor = linija.substr (4,length(linija)-4);

arr = odgovor.split("|");

poruka = arr[0]+ ": " + arr[1]+newline;

dodaj_u_chatbox(poruka);

}

if (kod eq "502"){

odgovor = linija.substr(4,length(linija)-4);

arr = odgovor.split("|");

_root.sredi_tabove.zastava = 1;

_root.globalna = arr[0];

poruka = arr[1];

gdje = _root.prozor[_root.globalna];

gdje.server += _root.globalna + ":" + poruka + newline;

gdje.server.scroll = gdje.server.maxscroll;

gdje.server.scroll +=1;

_root.sredi_tabove.gotoAndPlay(2);

_root.privatna = 1;

}

}

function trazi_listu(){

var zalistu = "303" //303 kod

trazenje liste

saljem = new XML(zalistu);

socket.send(saljem);

}

function sortiraj_niz(){

niz.sort();

}

function dodaj_na_listu(koga){

niz.push(koga);

niz.sort();

_root.prozor.lista.koji_put = 0;

_root.prozor.lista.gotoAndPlay(1);

}

function makni_sa_liste(koga){

for (var i = 0; i<niz.length; i++){

if (niz[i] eq koga){

pozicija = i;

}

Page 64: Integracija2

57

}

niz.splice(pozicija,1);

_root.prozor.lista.i=1;

_root.prozor.lista.koji_put = 1;

_root.prozor.lista.gotoAndPlay(2);

}

function dodaj_u_chatbox(poruka){

_root.prozor.chat.server += poruka;

_root.prozor.chat.server.scroll =

_root.prozor.chat.server.maxscroll;

_root.prozor.chat.server.scroll +=1;

}

function makni_tab(koga){

var zz = 1;

var obrisan =0;

for (var j=1; j<=_root.sredi_tabove.i;j++){

tabek = _root.prozor.tabovi["tab"+j];

if (tabek.korisnik eq koga){

chatzabrisat = _root.prozor[tabek.korisnik];

chatzabrisat.removeMovieClip();

obrisan = 1;

tabek.removeMovieClip();

_root.sredi_tabove.i--;

}

if (obrisan eq "0"){zz++;}

}

var r = zz-1;

trace ("RRRRRRR = "+r);

if (r ne "0"){

prijasnji = _root.prozor.tabovi["tab"+r];

_root.komesaljem = prijasnji.korisnik;

}

else

{

_root.komesaljem = "svima";

}

if (zz < _root.sredi_tabove.i){

for (var x=zz; x<=j;x++){

tabek = _root.prozor.tabovi["tab"+x];

tabek._x -=70;

}

}

}

function skrolaj_tabove_ljevo(){

hi = _root.sredi_tabove.i - 1;

if (_root.prozor.tabovi.tab._x ne (-70 * hi)){

_root.prozor.tabovi.tab._x-=70;

for (var j=1; j<=_root.sredi_tabove.i;j++){

tabek = _root.prozor.tabovi["tab"+j];

tabek._x -=70;

}

}

}

Page 65: Integracija2

58

function skrolaj_tabove_desno(){

if (_root.prozor.tabovi.tab._x ne "0"){

_root.prozor.tabovi.tab._x+=70;

for (var j=1; j<=_root.sredi_tabove.i;j++){

tabek = _root.prozor.tabovi["tab"+j];

tabek._x +=70;

}

}

}

function skrolaj_listu_gore(){

if (niz.length > 15){

if (_root.prozor.lista.puc._y ne "3"){

_root.prozor.lista.puc._y +=14;

for (var j=1; j<=niz.length; j++){

pucek = _root.prozor.lista["puc"+j];

pucek._y +=14;

}

}

}

}

function skrolaj_listu_dolje(){

if (niz.length > 15){

hi = niz.length - 1;

tt = hi - 13;

stani = _root.prozor.lista["puc"+tt];

if (stani._y ne "-10"){

_root.prozor.lista.puc._y-=14;

for (var j=1; j<=niz.length;j++){

pucek = _root.prozor.lista["puc"+j];

pucek._y -=14;

}

}

}

}

function spoji(){

socket = new XMLSocket();// Otvara novi XMLSocket objekt

socket.connect("kalkulator",7777); // Konekcija na server

socket.onXML = noviXML;

socket.onConnect = newConnection;

socket.onClose = endConnection;

}

//funkcija se pokrece svaki puta kada klijent promi poruku od servera

function noviXML(doc){

/////////////// kodovi koje server vraca prilikom logiranja

// kodovi

// 1 - Sve je u redu

// 2 - Korisnik ne postoji

// 3 - Kriva zaporka

////////////////////////////////////

linija = doc.toString();

provjeri_liniju(linija);

}

Page 66: Integracija2

59

//prva konekcija na server....salje se korisnicko ime i lozinka

function newConnection(success){

if (success){

if (_root.login.stisnuto eq "ok"){

var logiranje = "300 " +

login.unos.korisnik+"|"+login.unos.zaporka; //300 kod

logiranja

saljem = new XML(logiranje);

socket.send(saljem);

}

if (_root.login.stisnuto eq "gost")

{

var logiranje = "300 gost"; //saljem gosta

saljem = new XML(logiranje);

socket.send(saljem);

}

}

}

function endConnection() {

trace("------------------------------------------" );

trace("Hvala vam na koristenju ovog programa");

}

Page 67: Integracija2

60

E.2. Perl – serverski dio

use IO::Socket;

use IO::Select;

$cc = 0; # Broj konekcija

$p_guest = pack("B*", "0" x 512); # Broj gostiju

%users = (); # Hash kod korisnika

$/ = "\0";

$terminator = "\0";

# $lsn - socket prikljucnica servera postavljena na slusanje

$lsn = new IO::Socket::INET(Listen => 1,LocalPort => 7777, Reuse => 1,

Proto => 'tcp' ) or die ("Nisam se uspio pokrenuti: $!");

$lsn->blocking(0);

$lsn->autoflush(1);

warn "Server je podignut...\n";

# $sel - slekcija dolaznih konekcija

$sel = IO::Select->new($lsn);

while (@r_ready = $sel->can_read) {

foreach $client (@r_ready) {

if($client == $lsn) { #Kreiraj novog klijenta

$clnew = $client->accept;

$clnew->blocking(0);

$sel->add($clnew);

$cc++;

warn "101 Konekcija #$cc od ".$clnew->peerhost." na

portu ".$clnew->peerport . "\n";

my $msg = "100 Pozdrav ".$clnew->peerhost.", i dobro

nam dosli!".$terminator;

syswrite($clnew, $msg, length($msg));

}else{

$nread = sysread($client, $input, 1024);

chomp $input;

if($nread == 0) { bye(); next;}

warn "input=$input\n";

#-------

# Kodovi klijenta:

# 300 - login

# 301 - obicna poruka

# 302 - privatna poruka

# 303 - klijent trazi da mu se posalje lista

korisnika

#

# Kodovi servera:

# 500 login odgovor

# 501 - obicna poruka

# 502 - privatna poruka

# 503 - server salje listu korisnika klijentu

Page 68: Integracija2

61

# 504 - dosao je novi korisnik (salje svima poruku da

ga dodaju na listu)

# 505 - izasao je korisnik (salje svima poruku da ga

maknu s liste)

#

#-------

my $code = substr($input, 0, 3);

my $value = substr($input, 4);

#authorization

if($code == 300) {

my @login = split(/\|/, $value);

my $res = checkpass($login[0], $login[1]);

my $key, $val;

#Normal login

if($res == 1) {

my $usr = {

UNAME => $login[0],

ITIME => time(),

SOCKREF => $client

};

$users{$client} = $usr;

my $msg = "500 $login[0]\|1$terminator";

syswrite($users{$client}->{SOCKREF},

$msg, length($msg));

warn "User \"$login[0]\" login

uspjesan\n";

# -- salji svima poruku da je dosao

korisnik gost

sendall("504 ".$login[0]);

#Guest login

}elsif($res == 5) {

my $gnum = addguest();

if($gnum != -1) {

my $usr = {

UNAME =>

"Gost".sprintf('%03d', $gnum),

ITIME => time(),

SOCKREF => $client

};

$users{$client} = $usr;

my $msg = "500 ".$usr-

>{UNAME}."\|1$terminator";

syswrite($users{$client}-

>{SOCKREF}, $msg, length($msg));

warn "User \"".$usr->{UNAME}."\"

login uspjesan\n";

# -- salji svima poruku da je dosao

korisnik gost

sendall("504 ".$users{$client}-

>{UNAME});

}else{

warn "Previse gostiju.. ljudi

registrirajte se";

}

#Other cases

Page 69: Integracija2

62

}else{

warn "Error login $res occured\n";

my $msg = "500

$login[0]\|$res$terminator";

syswrite($client, $msg, length($msg));

bye();

}

#obicna poruka

}elsif($code == 301) {

sendall("501 ".$users{$client}-

>{UNAME}."\|".$value);

#privatna poruka

}elsif($code == 302) {

my @pvt = split(/\|/, $value, 2);

pvt($pvt[0], $pvt[1]);

# klijent je trazio listu

}elsif($code == 303) {

saljilistu();

}

}

}

}

#------------------------------------------------

#Funkcije

#------------------------------------------------

# $res values

# 1 - sve ok

# 2 - korisnik ne postoji

# 3 - krivi password

# 4 - korisnik vec logiran

sub checkpass {

my $user = shift;

my $pass = shift;

my $go = 1;

my $ret = 2; #korisnik ne postoji

my $len, $line, $ret, $key, $val, @usr_data;

if(lc($user) eq "gost") { return 5; } #gost se ne treba

provjeravat

## provjeri jel vec unutra

while (($key, $val) = each %users) {

warn "ret= $ret --provjeravam $user i $val->{UNAME} \n";

if ($user eq $val->{UNAME}) {return 4;} #korisnik vec

logiran

warn "sad je ret = $ret \n";

}

####

$/ = "\012";

$len = length($user);

if($len == 0) { return $ret; } #prazno polje user

open(DAT, "<korisnici.dat");

Page 70: Integracija2

63

while(($line = <DAT>) && ($go == 1)) {

if(substr($line, 0, $len) eq $user) {

@usr_data = split(/\|/, $line);

if($usr_data[1] eq $pass) {

$ret = 1; # password ok

$go = 0;

}else{

$ret = 3; #krivi password

$go = 0;

}

}

}

close(DAT);

$/ = "\0";

return $ret;

}

sub sendall {

my $msg = shift;

my $nw, $key, $val;

$msg .=$terminator;

if(length($users{$client}->{UNAME}) == 0) { return; } # ako nisi

logiran bjezi ca

while (($key, $val) = each %users) {

if((time() - $val->{ITIME}) > 600) { #timeout

warn "timeout\n";

}else{ # normalno

$nw = syswrite($val->{SOCKREF}, $msg, length($msg));

warn "Wrote $nw b to ", $val->{UNAME}, ",

key=$key\n";

if($nw > 0) { # nesto je posalo clientu

$val->{ITIME} = time();

}

}

}

}

sub pvt {

my $user = shift;

my $msg = shift;

my $nw, $key, $val;

if(length($users{$client}->{UNAME}) == 0) { return; } # ako nisi

logiran bjezi ca

$msg = "502 ".$users{$client}->{UNAME}."\|".$msg.$terminator;

#print "got private\n";

while (($key, $val) = each %users){ # mora odvrtit do kraja

liste, neznam zasto :(

print "compare: \"", $val->{UNAME}, "\" with \"$user\"\n";

if($val->{UNAME} eq $user) {

$nw = syswrite($val->{SOCKREF}, $msg, length($msg));

warn Privatna poruka za $user ($nw bytes)\n";

}

}

}

Page 71: Integracija2

64

sub saljilistu {

# --- funkcija koja posalje cjelu listu trenutnih korisnika

klijentu koji se upravo spojio

my $nw, $key, $val;

my $count = 0;

my $msg = "503 ";

while (($key, $val) = each %users){

if ($count == 0) {

$msg .= $val->{UNAME};

} else {

$msg .= "|" . $val->{UNAME};

}

$count++;

} #while

$msg .= $terminator;

$nw = syswrite($users{$client}->{SOCKREF}, $msg, length($msg));

warn "Poslana lista korisniku: " . $users{$client}->{UNAME} . "

($nw bytes)\n";

}

sub addguest {

my $unp = unpack("B*", $p_guest);

my $i, $len;

$len = length($unp);

for($i = 0; $i < $len; $i++) {

if(substr($unp, $i, 1) == 0) {

substr $unp, $i, 1, "1";

$p_guest = pack("B*", $unp);

return $i;

}

}

return -1;

}

sub delguest {

my $g = shift;

my $gnum = substr($g, 4);

my $unp = unpack("B*", $p_guest);

substr $unp, $gnum, 1, "0";

$p_guest = pack("B*", $unp);

}

sub bye() {

my $clname = $users{$client}->{UNAME};

warn "Disconnection from " . $client->peerhost . " on port " .

$client->peerport

. ". Client \"".$clname."\".\n";

if($clname =~ /gost\d+/i) { # Smanji broj gostiju

delguest($clname);

}

sendall("505 ".$clname);

delete $users{$client};

$sel->remove($client);

$client->close;

$cc--;

}

Page 72: Integracija2

65

Literatura

1. Beginning ASP.NET 1.1 with Visual C#® .NET 2003, Chris Ullman, John Kauffman,

Chris Hart, Dave Sussman, Daniel Maharry, Wiley Publishing, Inc., Indianapolis,

Indiana, 2004.

2. Jesse Liberty, Programming C#, 2nd

Edition, O’Reilly, 2002.

3. .NET Framework Essentials, 2nd

Edition, Thuan L. Thai, Hoang Lam, O’Reilly, 2002.

4. LOGIC PROGRAMMING AND PROLOG (2ED), Ulf Nilsson and Jan Maluszynski,

http://www.ida.liu.se/~ulfni/lpp (15. oţujka 2005)

5. Language Interoperability and Logic Programming Languages, Jonathan J. Cook,

University of Edinburgh, 2004

6. Prolog, A Tutorial Introduction, James Lu, Jerud J. Mead, Computer Science,

Department, Bucknell University, Lewisburg, PA 17387

7. P# manual, http://www.lfcs.ed.ac.uk/psharp [20. oţujka 2005]

8. Radovan Mario, Programiranje u Prologu, Informator, Zagreb, 1987.

9. http://www.dcs.ed.ac.uk/home/jjc/psharp/psharp-1.1/dlpsharp.html [20. oţujka 2005]

10. http://www.gnu.org/software/kawa [20. oţujka 2005]

11. http://www.gotdotnet.com/team/lang/ [20. oţujka 2005]

12. http://msdn.microsoft.com/net [23. travnja 2005]

13. http://kaminari.scitec.kobe-u.ac.jp/PrologCafe/ [23. travnja 2005]

14. http://www.ifcomputer.com/MINERVA/ [20. travnja 2005]

15. http://www.jython.org/ [7. svibnja2005]

16. http://pauillac.inria.fr/_diaz/gnu-prolog/ [20. oţujka, 2005.]

17. http://www.perl.org [26. travnja, 2005.]

18. http://www.perl.com [26. travnja, 2005]