GitHub
Tests: 12 • Commercial: 2 • Pet projects: 4 • Legacy: 4
Total: 22

.NET Framework

Test
2021

Project Request

ASP.NET MVC • C# • SQL Server
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2020

ProjectC

ASP.NET MVC • C# • JSON • jQuery
JSON data processing.
Test
2020

Vehicle Maintenance

ASP.NET MVC • VB.NET • JSON
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2019

Movie Navigator

ASP.NET MVC • VB.NET
Request information about movie from IMDB.
Test
2018

Customers Exchange

ASP.NET MVC • C# • SQL Server
Automated teller machine emulation.
Test
2016

ATM

ASP.NET MVC • C#
Automated teller machine emulation.

.NET Core

Pet project
2022

Mail Daemon

.NET 9 • Console • JSON
Utility to send mails with customizable settings.

Custom

Code
2024

Buns of code

.NET Framework • C# • JavaScript
Code snippets from my projects, ready to use; tiny tests; code examples.

PHP

Test
2024

Mediabox

PHP 8 • Laravel 11 • Vue.js • Composer • SQLite
Test project for media files management.
Test
2020

Loan Castle

PHP • MariaDB
Jums jāizstrādā kāda lielāk projekta prototips. Izstrādājot prototipu, paturiet prātā, ka projektam attīstoties, šo prototipu varētu vajadzēt pilnveidot.
Test
2020

Content Management

PHP • MySQL • AJAX
Создать простой сайт, где будет страница с формой для авторизации и страница для авторизованного пользователя.
Test
2019

Laravel

PHP • Laravel • Vue.js • Composer • SQLite
Izveidot aplikāciju, kura ik pēc noteikta intervāla (60 sekundes) veic ierakstu datubāzē izmantojot Laravel freimworka iebūvēto funkcionalitāti.
Test
2019

Phone Check

PHP • JavaScript • JSON • Docker
Implement application to detect country by phone number.

Frontend

Test
2021

Forex Wall

npm • React
For this exercise, what we need is a simple live wall for tracking currencies.

Business projects

Commercial
2008

Certification Center

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Dapper • JavaScript • jQuery • Git
Transport registration and certification services in Latvia, Customer Relationship Management.
Commercial
2000

Amerikas Auto

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Entity Framework • JavaScript • jQuery • Git
Car service and spare parts for all USA and European car models, Customer Relationship Management.

Pet projects

Pet project
2023

Geolocation Assistant

.NET 8 • ASP.NET Core • C# • Web API • JSON • Git
Website for determining geolocation by IP or geotagged photo.
Pet project
2008

Web Dynamics

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
Software development blog. Articles, books, videos, content management.
Pet project
2000

Blackball

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • XML • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
My entertainment portal created from scratch.

Good old times

Legacy
2000

DOS Clock

Turbo Pascal • Assembler
Digital clock.
Legacy
2000

BrainOut

Turbo Pascal • Assembler
Tank battle game.
Legacy
1999

Airport Administrator

Turbo Pascal
Курсовая работа в институте.
Legacy
1998

Atomizer

Turbo Pascal • Assembler
Atomizer, aka «Studio2D». Graphic raster editor. AGI is my own «Atomizer Generated Image» file format.

BrainOut

2000 Legacy

Tank battle game.

Turbo Pascal Assembler
Information
Source code
Root / BOshared.PAS
{$A+,B+,D+,E-,F-,G+,I+,L+,N+,O-,P-,Q-,R-,S+,T-,V+,X+,Y+} {$M 16384, 0, 65535} unit BOshared; interface uses crt, graph, dos, globals, general, mouse; const PATHTO_DATA = 'DATA\'; MAXTANKS = 100; INACTIVECOLOR = 7; NAMESELCOL2 = 8; FIELDWIDTH = 484; { field length } FIELDHEIGhT = 300; DELTACENTER = 9; type switchstatus = ( first, second ); tankarray = array [ 0..23, 0..59 ] of shortint; TPlayer1 = record name : string; tanks : integer; score : longint; tankbox : ^tankarray; getcagex : shortint; getcagey : shortint; end; TPlayer2 = record name : string; tanks : integer; score : longint; tankbox : ^tankarray; getcagex : shortint; getcagey : shortint; end; TMatchStat = record hour1 : byte; minute1 : byte; second1 : byte; second2 : byte; sec100 : byte; hour2 : byte; minute2 : byte; hour : byte; end; var player1 : TPlayer1; player2 : TPlayer2; playerswitch : switchstatus; gamestarted : boolean; tanksizex : byte; tanksizey : byte; center : integer; matchstat : TMatchStat; procedure displayplayersinfo; procedure drawcage( cagexpos, cageypos : byte; selectedplayer : switchstatus ); function mainmenu : byte; procedure playgame; procedure quit; procedure rankingtable; procedure visfield; Implementation {----------------------------------------------------------------------------} procedure displayplayersinfo; begin bardeluxe( 510, 0, 200, 100, 1, 0 ); bardeluxe( 510, 305, 200, 100, 1, 0 ); case playerswitch of first : begin { 1 player info /active/ } if player1.tanks > player2.tanks then setcolor( 14 ) else setcolor( 15 ); settextstyle( 3, 0, 1 ); outtextxy( 520, 0, player1.name ); outtextxy( 640, 10, inttostr( player1.score )); if player1.tanks < 10 then setcolor( 12 ) else setcolor( 15 ); settextstyle( 2, 0, 0 ); outtextxy( 530, 40, 'Tanks -> ' + inttostr( player1.tanks )); { 2 player info /inactive/ } setcolor( INACTIVECOLOR ); settextstyle( 3, 0, 1 ); outtextxy( 520, 310, player2.name ); outtextxy( 640, 320, inttostr( player2.score )); settextstyle( 2, 0, 0 ); outtextxy( 530, 350, 'Tanks -> ' + inttostr( player2.tanks )); setlinestyle( 3, 0, 0 ); setcolor( 10 ); rectangle( 0, 0, FIELDWIDTH, getmaxy div 2 - 6 ); setcolor( 7 ); rectangle( 0, getmaxy div 2 + 6, FIELDWIDTH, getmaxy ); end; second : begin { 1 player info /inactive/ } setcolor( INACTIVECOLOR ); settextstyle( 3, 0, 1 ); outtextxy( 520, 0, player1.name ); outtextxy( 640, 10, inttostr( player1.score )); settextstyle( 2, 0, 0 ); outtextxy( 530, 40, 'Tanks -> ' + inttostr( player1.tanks )); { 2 player info /active/ } if player1.tanks < player2.tanks then setcolor( 14 ) else setcolor( 15 ); settextstyle( 3, 0, 1 ); outtextxy( 520, 310, player2.name ); outtextxy( 640, 320, inttostr( player2.score )); settextstyle( 2, 0, 0 ); if player2.tanks < 10 then setcolor( 12 ) else setcolor( 15 ); outtextxy( 530, 350, 'Tanks -> ' + inttostr( player2.tanks )); setlinestyle( 3, 0, 0 ); setcolor( 7 ); rectangle( 0, 0, FIELDWIDTH, getmaxy div 2 - 6 ); setcolor( 10 ); rectangle( 0, getmaxy div 2 + 6, FIELDWIDTH, getmaxy ); end; end; { case } end; {----------------------------------------------------------------------------} procedure drawcage; begin setlinestyle( 0, 0, 0 ); if selectedplayer = first then rectangle( 2 + cagexpos * (tanksizex+1), center - DELTACENTER - cageypos * (tanksizey+1) - (tanksizey+1), 2 + cagexpos * (tanksizex+1) + (tanksizex+1), center - DELTACENTER - cageypos * (tanksizey+1) ) else rectangle( 2 + cagexpos * (tanksizex+1), center + DELTACENTER + cageypos * (tanksizey+1) + (tanksizey+1), 2 + cagexpos * (tanksizex+1) + (tanksizex+1), center + DELTACENTER + cageypos * (tanksizey+1) ); end; {----------------------------------------------------------------------------} function mainmenu; const MENUITEMS : array [ 0..5 ] of string=( 'New game', 'Return', 'Options', 'High Scores', 'Credits', 'Quit' ); CONTEXTHELP : array [ 0..5 ] of string=( 'Start new game with players personalizing and match rules.', 'Return to current game.', 'Configure game global options, such as rules, etc.', 'View ranking table.', 'Information about game and me.', 'Quit the game.' ); MENUYPOS = 230; MAXITEMS = 6; var menujumper : shortint; procedure vismenu; begin for counter := 0 to MAXITEMS-1 do begin if counter = menujumper then setcolor( 12 ) else setcolor( 15 ); if not gamestarted and (counter = 1) then setcolor( 7 ); settextstyle( 1, 0, 0 ); outtextxy( ( getmaxx - textwidth( MENUITEMS[ counter ]) ) div 2, MENUYPOS + counter * ( textheight( MENUITEMS[ counter ] ) + 5 ), MENUITEMS[ counter ]); if counter = menujumper then { display context help } begin bardeluxe( 0, getmaxy - 25, getmaxx, 25, 10, 3 ); setcolor( 14 ); settextstyle( 0, 0, 0 ); outtextxy(( getmaxx - textwidth( CONTEXTHELP[ counter ]) ) div 2, 582, CONTEXTHELP[ counter ]); end; end; end; { vismenu } begin menujumper := 0; cleardevice; bardeluxe( 0, 0, getmaxx, getmaxy, 11, 3 ); bardeluxe( 5, 6, 348, 31, 10, 3 ); setcolor( 1 ); settextstyle( 8, 0, 1 ); for counter := 0 to 2 do outtextxy( 18 - counter, 6 - counter, '2001 Created by Sergei Drozdov' ); setcolor( 9 ); outtextxy( 17 - counter, 5 - counter, '2001 Created by Sergei Drozdov' ); setcolor( 3 ); settextstyle( 3, 0, 9 ); for counter := 0 to 8 do outtextxy(( getmaxx - textwidth( 'Brains Out' )) div 2 - counter + 11, 70 - counter, 'Brains Out' ); setcolor( 4 ); for counter := 8 to 11 do outtextxy(( getmaxx - textwidth( 'Brains Out' )) div 2 - counter + 11, 70 - counter, 'Brains Out' ); vismenu; repeat oldmousex := mousex; oldmousey := mousey; mouseread( mousex, mousey, mouseButton ); if mousemove then mousedraw; { mouse in menu area } if (( mousex > 305 ) and ( mousex < 490 )) and (( mousey > 230 ) and ( mousey < 445 )) then begin if mouseButton = 1 then { LMB } if not gamestarted and (menujumper = 1) then else begin mainmenu := menujumper; exit; end; if mousemove then { jump to menu items } begin menujumper := (mousey - 230) div ( textheight( MENUITEMS[0] ) + 5 ); vismenu; end; end; if keypressed then begin key := readkey; case key of ENTER : if not gamestarted and (menujumper = 1) then else begin mainmenu := menujumper; exit; end; ESC : quit; #0 : begin key := readkey; case key of DOWNARROW_ext : begin inc( menujumper ); if not gamestarted and (menujumper = 1) then inc( menujumper ); end; UPARROW_ext : begin dec( menujumper ); if not gamestarted and (menujumper = 1) then dec( menujumper ); end; end; { case } if menujumper < 0 then menujumper := (MAXITEMS-1); if menujumper = MAXITEMS then menujumper := 0; end; end; vismenu; end; until false; end; {----------------------------------------------------------------------------} procedure playgame; begin repeat oldmousex := mousex; oldmousey := mousey; mouseread( mousex, mousey, mouseButton ); if mousemove then begin if (( mousex > 3 ) and ( mousex < FIELDWIDTH )) and (( mousey > 3 ) and ( mousey < center )) then begin mousehide; { hide mouse when in play area } if playerswitch = first then begin setcolor( 8 ); drawcage( player1.getcagex, player1.getcagey, playerswitch ); player1.getcagex := mousex div 7; player1.getcagey := 23 - mousey div 11 ; if player1.getcagex > 59 then player1.getcagex := 59; if player1.getcagey < 0 then player1.getcagey := 0; setcolor( 7 ); drawcage( player1.getcagex, player1.getcagey, playerswitch ); bardeluxe( 0,0,30,30,1,0); outtextxy( 5,5,inttostr(player2.tankbox^[player1.getcagex, player1.getcagey])); end; end else mousedraw; setlinestyle( 0, 0, 0 ); if (( mousex > 510 ) and ( mousex < 638 )) and (( mousey > 580 ) and ( mousey < 599 )) then begin setcolor( 9 ); settextstyle( 2, 0, 0 ); rectangle( 510, 580, 638, 599 ); bardeluxe( 511, 581, 126, 17, 1, 1 ); setcolor( 14 ); outtextxy( 530, 583, 'Match statistics ' ); end else begin setcolor( 7 ); settextstyle( 2, 0, 0 ); rectangle( 510, 580, 638, 599 ); bardeluxe( 511, 581, 126, 17, 1, 8 ); outtextxy( 530, 583, 'Match statistics ' ); end; if (( mousex > 662 ) and ( mousex < 790 )) and (( mousey > 580 ) and ( mousey < 599 )) then begin setcolor( 9 ); settextstyle( 2, 0, 0 ); rectangle( 662, 580, 790, 599 ); bardeluxe( 663, 581, 126, 17, 1, 1 ); setcolor( 14 ); outtextxy( 700, 583, 'Main menu' ); end else begin setcolor( 7 ); settextstyle( 2, 0, 0 ); rectangle( 662, 580, 790, 599 ); bardeluxe( 663, 581, 126, 17, 1, 8 ); outtextxy( 700, 583, 'Main menu' ); end; end; { mouse move } if mouseButton = 1 then { LMB } if not disableLMB then begin disableLMB := true; { if pressed on 'main menu' then exit to main menu } if (( mousex > 662 ) and ( mousex < 790 )) and (( mousey > 580 ) and ( mousey < 599 )) then exit; if playerswitch = first then { first player active } if ( (mousex > 0) and (mousex < FIELDWIDTH) ) and ( (mousey > 0) and (mousey < center) ) then begin if player2.tankbox^[ player1.getcagex, player1.getcagey ] = 0 then begin player2.tankbox^[ player1.getcagex, player1.getcagey ] := 3; visAGI( 3 + player1.getcagex * (tanksizex+1), center + DELTACENTER + player1.getcagey * (tanksizey+1) + 1, PATHTO_DATA + 'blast.agi' ); end; if player2.tankbox^[ player1.getcagex, player1.getcagey ] = 1 then begin { player 2 tank destroyed } player2.tankbox^[ player1.getcagex, player1.getcagey ] := 2; dec( player2.tanks ); inc( player1.score, 10 ); visAGI( 3 + player1.getcagex * (tanksizex+1), center + DELTACENTER + player1.getcagey * (tanksizey+1) + 1, PATHTO_DATA + 'tank2_w.agi' ); end; if player2.tanks = 0 then begin displayplayersinfo; setcolor(14); settextstyle(1,0,0); outtextxy(200,200, player1.name + ' winner!' ); readkey; closegraph; halt; end; setcolor( 4 ); drawcage( player1.getcagex, player1.getcagey, playerswitch ); playerswitch := second; setcolor( 7 ); drawcage( player2.getcagex, player2.getcagey, playerswitch ); displayplayersinfo; end; end { LMB } else disableLMB := false; if KeyPressed then { keyboard control } begin key := readkey; if key = #27 then exit; { exit to main menu } if playerswitch = second then case key of ESC : exit; #0 : begin key := readkey; setcolor( 8 ); drawcage( player2.getcagex, player2.getcagey, playerswitch ); if playerswitch=second then case key of LEFTARROW_ext : dec( player2.getcagex ); RIGHTARROW_ext : inc( player2.getcagex ); UPARROW_ext : dec( player2.getcagey ); DOWNARROW_ext : inc( player2.getcagey ); end; { case } if player2.getcagex < 0 then player2.getcagex := 59; if player2.getcagex > 59 then player2.getcagex := 0; if player2.getcagey < 0 then player2.getcagey := 23; if player2.getcagey > 23 then player2.getcagey := 0; setcolor( 7 ); drawcage( player2.getcagex, player2.getcagey, playerswitch ); end; SPACE : begin if player1.tankbox^[ player2.getcagex, player2.getcagey ] = 0 then begin player1.tankbox^[ player2.getcagex, player2.getcagey ] := 3; visAGI( 3 + player2.getcagex * (tanksizex+1), center - DELTACENTER - player2.getcagey * (tanksizey+1) - (tanksizey+1) + 1, PATHTO_DATA + 'blast.agi' ); end; if player1.tankbox^[ player2.getcagex, player2.getcagey ] = 1 then begin { player 1 tank destroyed } player1.tankbox^[ player2.getcagex, player2.getcagey ] := 2; dec( player1.tanks ); inc( player2.score, 10 ); visAGI( 3 + player2.getcagex * (tanksizex+1), center - DELTACENTER - player2.getcagey * (tanksizey+1) - (tanksizey+1) + 1, PATHTO_DATA + 'tank1_w.agi' ); end; if player1.tanks = 0 then begin displayplayersinfo; setcolor(14); settextstyle(1,0,0); outtextxy(200,200, player2.name + ' winner!' ); readkey; closegraph; halt; end; setcolor( 4 ); drawcage( player2.getcagex, player2.getcagey, playerswitch ); playerswitch := first; setcolor( 7 ); drawcage( player1.getcagex, player1.getcagey, playerswitch ); displayplayersinfo; end; end; { case } end; until false; end; {----------------------------------------------------------------------------} procedure quit; begin closegraph; textbackground( 0 ); clrscr; textcolor( 7 ); writeln( 'Brains Out' ); writeln( '(c) 2001 Created by Sergeant Skeleton' ); writeln; textcolor( 2 ); writeln( '-=[ Sergei Drozdov ]=-' ); write( 'e-mail : ' ); textcolor( 7 ); write( 'punksalive@mail.lv' ); textcolor( 2 ); write( ' or ' ); textcolor( 7 ); writeln( 'punksalive@navigators.lv' ); textcolor( 2 ); write( 'phone : ' ); textcolor( 7 ); writeln( '(53) 42169' ); textcolor( 2 ); write( 'Address : ' ); textcolor( 7 ); writeln( 'Rigas iela 8a-48, Livani, LV-5316, Latvija' ); textcolor( 7 ); dispose( player1.tankbox ); dispose( player2.tankbox ); halt; end; {----------------------------------------------------------------------------} procedure rankingtable; type TRankingTable = record name : string; score : longint; end; var ranktable : array [ 0..39 ] of ^TRankingTable; begin { assign( f, 'brains.his' ); reset( f, 1 ); settextstyle( 2, 0, 0 ); for counter := 0 to 39 do begin new( ranktable^[counter].name); end; for counter := 0 to 39 do begin blockread( f, ranktable[counter].name, 10 ); blockread( f, ranktable[counter].score, 10 ); outtextxy( 200, 20 + counter * 15, ranktable[counter].name+ ' ..................................... ' + inttostr(ranktable[counter].score) ); end; close( f ); dispose( ranktable ); repeat until keypressed; } end; {----------------------------------------------------------------------------} procedure visfield; begin { draw fields separator } bardeluxe( 0, center - 2, getmaxx, 4, 5, 6 ); setcolor( 8 ); rectangle( 500, 572, 799, 573 ); { two inactive buttons } setcolor( 7 ); settextstyle( 2, 0, 0 ); rectangle( 510, 580, 638, 599 ); bardeluxe( 511, 581, 126, 17, 1, 8 ); outtextxy( 530, 583, 'Match statistics ' ); rectangle( 662, 580, 790, 599 ); bardeluxe( 663, 581, 126, 17, 1, 8 ); outtextxy( 700, 583, 'Main menu' ); { draw grid } setlinestyle( 0, 0, 0 ); setcolor( 8 ); for tmpy := 0 to 23 do for tmpx := 0 to 59 do begin drawcage( tmpx, tmpy, first ); drawcage( tmpx, tmpy, second ); end; if gamestarted = false then { game not started } begin { tanks initilization } for tmpy := 0 to 23 do for tmpx := 0 to 59 do begin if random( MAXTANKS ) = 1 then begin inc( player1.tanks ); player1.tankbox^[ tmpx, tmpy ] := 1; end else player1.tankbox^[ tmpx, tmpy ] := 0; if random( MAXTANKS ) = 1 then begin inc( player2.tanks ); player2.tankbox^[ tmpx, tmpy ] := 1; end else player2.tankbox^[ tmpx, tmpy ] := 0; end; end; { for tmpy := 0 to 23 do for tmpx := 0 to 59 do begin setcolor(10); settextstyle(2,0,0); outtextxy( 3+tmpx*7, tmpy*8, inttostr(player2.tankbox^[ tmpx, tmpy ])); end; } { terrain and tanks visualization } for tmpy := 0 to 23 do for tmpx := 0 to 59 do begin if player1.tankbox^[ tmpx, 23 - tmpy ] = 1 then { display tank } visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1, PATHTO_DATA + 'tank1.agi' ); if player1.tankbox^[ tmpx, 23 - tmpy ] = 2 then { display wrecked tank } visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1, PATHTO_DATA + 'tank1_w.agi' ); if player1.tankbox^[ tmpx, 23 - tmpy ] = 3 then { display wrecked terrain } visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1, PATHTO_DATA + 'blast.agi' ); if player2.tankbox^[ tmpx, tmpy ] = 1 then { display tank } visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + 1, PATHTO_DATA + 'tank2.agi' ); if player2.tankbox^[ tmpx, tmpy ] = 2 then { display wrecked tank } visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + (tanksizey+1) + 1, PATHTO_DATA + 'tank2_w.agi' ); if player2.tankbox^[ tmpx, tmpy ] = 3 then { display wrecked terrain } visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + (tanksizey+1) + 1, PATHTO_DATA + 'blast.agi' ); end; { players cursors visualization } case playerswitch of first : begin setcolor( 7 ); drawcage( player1.getcagex, player1.getcagey, first ); setcolor( 4 ); drawcage( player2.getcagex, player2.getcagey, second ); end; second : begin setcolor( 4 ); drawcage( player1.getcagex, player1.getcagey, first ); setcolor( 7 ); drawcage( player2.getcagex, player2.getcagey, second ); end; end; { case } end; {----------------------------------------------------------------------------} end. { shared components for this game }