# From Requirements to Source Code: Evolution of Behavioral Programs
## 3 A Short Primer on Context-Oriented Behavioral Programming
```
1//Populatecontextwithallcells
2 for(leti=0;i<3;i++)
3 for(letj=0;j<3;j++)
4 ctx.populate(ctx.Entity('cell('+i+','+j')','cell',{at:{i:i,j:j}}))
5
6//Populatecontextwithalllines
7 for(leti=0;i<3;i++){
8 ctx.populate(ctx.Entity('row('+i+')','line',
9{cells:[[i:i,j;0],{i:i,j:1},{i:i,j:2}]}))
10 ctx.populate(ctx.Entity('col('+i+')','line',
11{cells:[[i:0,j:i},{i:1,j:i},{i:2,j:i}]{i:2,j:i}]{i:2,j:i}]{i:2,j:i}]})
12}ctx.populate(ctx.Entity('diag(0)','line',
14{cells:[[i:0,j:0],{i:1,j:1},{i:2,j:2}]{i:2,j:2}]{i:2,j:2}]{i:2,j:0}]})
15 ctx.populate(ctx.Entity('diag(1)','line',
16{cells:[[i:2,j:0],{i:1,j:1},{i:0,j:2}]{i:0,j:2}]{i:2,j:0}]})
17
18//Registerqueriesonthemotextualdata
19 ctx.registerQuery('Cell.Any\",
20 ctx.Entity('cell(0,0)','cell',{at:{i:0,j:0}}),
21}dots
22 ctx.Entity('cell(2,2)','cell',{at:{i:2,j:2}})
23}]
24 ctx.registerQuery(\"Line.Any\",
25 ctx.Entity('line(0)','line',{cells:[[i:0,j:0,{i:0,j:1},{i:0,j:2}]}),
26}dots
27 ctx.Entity('line(7)','line',{cells:[[i:0,j:2},{i:1,j:1},{i:2,j:0}]])
```
1//Defineevents:
2 constX=cell=>Event('X',cell)
3 constO=cell=>Event('O',cell)
4 constXWin=Event('XWin')
5 constOWin=Event('OWin')
6 constTie=Event('Tie')
7
8//Defineeventsets
9 constAnyX=EventSet('AnyX',event=>event.name==='X')
10 constAnyO=EventSet('AnyO',event=>event.name==='O')
11
12//Req.1:Acellcanbemarkedonlyonce. 13 bthread(\"Donotmarkcelltwice\",\"Cell.Any\",function(cell){
14 sync({waitFor:[X(cell.at),O(cell.at)]})
15 sync({block:[X(cell.at),O(cell.at)]})
16})
17
18//Req.2:XandOplayinturns;Xstarts. 19 bthread(\"Enforceturns\",function(){
20 while(true){
21 sync({waitFor:AnyX,block:AnyQ})
22 sync({waitFor:AnyO,block:AnyX})
23}
24})
25
26//Req.3:Thefirstplayertogetthreemarksinalinesisthewinner. 27 bthread(\"DetectXwin\",\"Line.Any\",function(1){
28 sync({waitFor:[X(1.cells[0]),X(1.cells[1]),X(1.cells[2])]})
29 sync({waitFor:[X(1.cells[0]),X(1.cells[1]),X(1.cells[2])]})
30 sync({waitFor:[X(1.cells[0]),X(1.cells[1]),X(1.cells[2])]})
31 sync({request:XWin,block:bp.not(XWin)})
32});
33
34//Req.3:Thefirstplayertogetthreemarksinalinesisthewinner. 35 bthread(\"DetectOwin\",\"Line.Any\",function(1){
36 sync({waitFor:[O(1.cells[0]),O(1.cells[1]),O(1.cells[2])]})
37 sync({waitFor:[O(1.cells[0]),O(1.cells[1]),O(1.cells[2])]})
38 sync({waitFor:[O(1.cells[0]),O(1.cells[1]),O(1.cells[2])]})
39 sync({request:OWin,block:bp.not(OWin)})
40})
41
42//Req.4:Ifnoplayerwonandallninesquaresaremarked,declareatie. 43 bthread(\"Detecttie\",function(){
44 for(leti=0;i<9;i++)
45 sync({waitFor:[AnyX,AnyO]})
46 sync(
47{request:Tie,waitFor:[XWin,OWin],block:bp.not([XWin,OWin,Tie])})
48})
49
50//Req.5:Thegameendsuponatieorawin. 51 bthread(\"Endgame\",function(){
52 sync({waitFor:[XWin,OWin,Tie]})
53 sync({block:bp.all()})
54})
```
**Listing 2**Tic-tac-toe rules, specified in COBPjs. ```B-threads in COBP interact through events; thus, we begin with the definition of the possible events in the game (lines 1-6). X and O are functions that takes a cell entity and return an event with the name X or O, respectively, and the given cell as the event's data. A set of events can be defined using an array of events (e.g., line 14), or using a function that takes an event and returns true if the event is in the set (i.e., AnyX and AnyO in lines 9-10). Another way to define event sets is using bp.not(e) and bp.all functions (i.e., lines 39 and 53). The first returns true for events that are not e, and the latter for all events. The first b-thread (lines 1-5) specifies the first requirement: a cell can be marked only once. The context of the requirement is a cell, therefore the b-thread is bound to the Cell.Any query. As a result, for each answer to this query (i.e., for each cell entity), the execution mechanism of COBPjs will spawn and execute a live-copy of this behavior with the specific answer (i.e., cell) given as a parameter. The behavior itself (lines 3-4) waits for X or O events with this cell and then blocks any attempt to place another X or O there.