<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Huseyn Ismayilov on Medium]]></title>
        <description><![CDATA[Stories by Huseyn Ismayilov on Medium]]></description>
        <link>https://medium.com/@huseynismayilov?source=rss-fad42706d941------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*rCwJ8_NeTubH2unsO_reAg.jpeg</url>
            <title>Stories by Huseyn Ismayilov on Medium</title>
            <link>https://medium.com/@huseynismayilov?source=rss-fad42706d941------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 16:24:04 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@huseynismayilov/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[How Foveated Rendering Enhances Performance in VR]]></title>
            <link>https://huseynismayilov.medium.com/foveated-rendering-e87d62d5cd25?source=rss-fad42706d941------2</link>
            <guid isPermaLink="false">https://medium.com/p/e87d62d5cd25</guid>
            <category><![CDATA[virtual-reality]]></category>
            <category><![CDATA[computer-graphics]]></category>
            <category><![CDATA[rendering]]></category>
            <category><![CDATA[foveated-rendering]]></category>
            <dc:creator><![CDATA[Huseyn Ismayilov]]></dc:creator>
            <pubDate>Tue, 05 Nov 2024 18:48:17 GMT</pubDate>
            <atom:updated>2024-11-05T18:48:17.122Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>Nowadays, we interact with many people and witness various adventures in real life. However, as we know, some activities also negatively affect people, so there are multiple limitations. At this point, a question arises: is there a life without these limitations? In response to this question, engineers discovered one of the most popular technologies — virtual reality.</p><p>Of course, achieving this type of reality is not an easy task. Adapting real-life objects and scenes directly to virtual life is very costly. For this reason, there are many techniques to optimize the rendering of these objects and scenes, to work more efficiently, and to offer the user a more realistic and vivid image. In this article, I will discuss the current problems in virtual reality devices, solutions to these problems with foveated rendering, and its benefits in optimizing and giving the user a better virtual reality experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eRrnHDCvMXcBo1TBAbRSXg.jpeg" /><figcaption>Virtual Reality offers an engaging and futuristic experience. This picture depicts a girl exploring the immersive virtual world with VR glasses.</figcaption></figure><h3>The Challenges in VR</h3><p>Rendering a highly detailed scene on the 1,830 x 2,928 display at 90fps is already a challenge. How many calculations are performed in one second can be calculated this way: 1830px × 2928px (the number of pixels across the width and length of the screen) × 90 FPS (the number of frames in one second) × 100FLOPs (floating point operations per pixel) = 48,245,760,000 FLOPs (floating point operations per second)= 48.2 GFLOPS.</p><p>And to create a true-to-life experience, we need to reduce pixel aliasing artifacts as much as possible. If you wonder, anti-aliasing is a technique used in computer graphics to smooth out jagged edges in digital images. As a result, the actual render resolution is much larger: when using multi-sampled antialiasing, we render an image at 4x the display resolution. As a result, just rendering the screen takes 192.8 GFLOPs worth of calculations per second. In addition, processes such as advanced shading, post-processing effects, distortion correction, physics and interaction calculations, and eye tracking increase these calculations even more. Can you imagine how big it is?</p><p>Although modern GPUs are very powerful, there are limited resources available to render high-quality images at 90 FPS. To avoid having to decrease the image quality, foveated rendering greatly reduces the cost of the 210-degree field of view (FOV) by only rendering the area their eye is focused on in high detail.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JB36vjNHdax7JtrkYAM6pQ.jpeg" /><figcaption>The focus area rendered using foveated rendering.</figcaption></figure><h3>How it works</h3><p>Foveated rendering is a device-performance optimization technique that concentrates rendering resources on the area of the display where the user looks. The content in the area immediately surrounding the user’s gaze point is rendered in high resolution. The rest of the image — the part in the user’s peripheral vision — is rendered at lower resolutions, reducing the resources needed to render a scene without any perceived degradation in user experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gdiInYNI77TrTS4d9aHtHQ.jpeg" /><figcaption>A real example of foveated rendering. While the center is clearer, the image becomes increasingly blurry at the edges.</figcaption></figure><h4>Static (Fixed) Foveated Rendering</h4><p>The static approach to foveated rendering, or what some call fixed foveated rendering, assumes that the user focuses on the center of the screen (which is usually true). The illustration shows how fixed foveated rendering works in a VR headset by portioning the screen into hardcoded zones. The assumed region of user attention — indicated by the white part in the center of the screen — is rendered at 100%. The gray sections are rendered at medium resolution, and the light blue areas at low resolution, reducing the resources needed to render the full scene.</p><p>You can implement static foveated rendering on just about any device, and you will likely see some degree of resource optimization. Still, it does not always yield an optimum user experience. The level of peripheral distortion introduced by early generations of lenses provided an opportunity to reduce the resolution in areas where the image would be blurred anyway. However, as lens quality has risen, the entire field of view needs to be rendered in high resolution.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/1*WUOUXdv9mFtPkQketns2Cg.png" /><figcaption>Optimized areas on the screen during static foveated rendering.</figcaption></figure><h4>Dynamic Foveated Rendering</h4><p>Dynamic foveated rendering leverages the actual region of the user’s attention to fully render a small portion of the image (illustrated by the white area), expanding outward to medium (gray) and low resolution (light blue) with no degradation of quality or user experience. To implement dynamic foveated rendering, you need accurate, low latency eye tracking that can repeatedly deliver the exact gaze point of the user in real-time.</p><p>Some benchmark tests done on dynamic foveated rendering have yielded phenomenal results. In one that ran on a Pico headset with the Unity engine, GPU shading load dropped by up to 72% with an average of about 60%. These tests revealed a drastic improvement in the stability of frame rates, which didn’t drop below 90 FPS with dynamic foveated rendering enabled. And that’s great for user experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/1*TaK7e09Il-OT3viGS2DuLg.png" /><figcaption>Optimized areas on the screen during dynamic foveated rendering.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-EspCpxNvAqNw-wqVc6gPA.png" /><figcaption>The differences between static and dynamic foveated rendering.</figcaption></figure><h3>Benefits</h3><h4>Rendering</h4><p>Rendering in XR is done via multi-stage pipelines. Depending on the rendering architecture of the device, foveated rendering can deliver performance savings in specific pipeline parts, which in turn can translate to faster rendering.</p><p>Overall processing savings are relative to the proportion of the rendering pipeline processing that can be foveated. In both absolute and relative terms, savings increase with increasing resolution and pixel/fragment shader or lighting complexity. They increase the gains achieved by reducing the per-pixel processing costs and tend to increase the relative processing load of the parts of the pipeline that can be foveated.</p><p>Based on Tobii testing of Qualcomm foveated rendering and NVIDIA Variable Rate Shading foveated rendering together with third party testing of Logarithmic Remapping deferred foveated rendering have all shown 60% or greater net processing cost reductions to the foveated portions of their respective rendering pipelines.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*WMHh2qAcmtt2b2bi7Q-xaQ.jpeg" /><figcaption>The performance optimizations with and without foveated rendering.</figcaption></figure><h4>Power Savings</h4><p>These processing savings can also translate to power savings. GPU power consumption typically relates to a combination of GPU frequency and GPU utilization, where foveation can only directly affect GPU utilization.</p><p>Application developers do not generally have direct control over GPU frequency, however for hardware manufacturers that do (or can expose the control), there are some potentially significant benefits to power consumption.</p><p>Increasing GPU frequency comes at an exponentially increasing cost in terms of power consumption. Reducing the frequency even slightly can produce significant power savings. The exponential nature of the power consumption and the power floor required to maintain operation does however mean that returns decrease with larger frequency reductions.</p><p>As a simplified example, an application that is only utilizing the GPU for 50% of each frame could potentially run at half the frequency, which would consume far less power.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R8kiDtMfObb9SDBF2Gczwg.png" /><figcaption>Optimizations in GPU frequency and power consumption achieved with foveated rendering</figcaption></figure><h4>Visual Quality</h4><p>Foveated rendering can also allow for better visual quality of your application. Since fewer resources have to be spent on rendering peripheral areas, the freed capacity can be reinvested in graphical fidelity. Several scenarios are possible:</p><ul><li>The freed GPU time can be used for more complex lighting and shaders. Any computation that primarily works on fragments or pixels can benefit here.</li><li>Increasing resolution is another alternative. With the trend to larger resolutions in XR, the foveated regions will benefit particularly. With fixed-resolution displays, there may not be the option to increase the final resolution. However, super-sampling (rendering at a higher resolution and then filtering and shrinking the images) directed by eye tracking can give increased detail and better anti-aliasing with the processing more effectively directed than with MSAA or non-eye-tracked super-sampling.</li><li>Dynamic foveation improves the visual quality over static foveation. While static foveation allows for some savings, they are dictated by the optical properties of the device’s lenses. Today, the effect of static foveation is already quite visible, and with improved optics and a larger field of views, the potential savings will diminish. Dynamic eye tracking foveation, in contrast, can be almost imperceivable, hence improving the visual quality.</li></ul><p>Foveation, by definition, introduces some artifacts in the user’s visual periphery due to the lowered rendering quality. The goal is to ensure these artifacts stay below the user’s perception threshold. Similarly to how static foveation can hide these artifacts in the device lenses’ zone of imperfection, foveated rendering can hide them in the user’s peripheral vision.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d9JBGgWit_hgeKiys4K3-A.jpeg" /><figcaption>Improvements in visual quality and user experience offered by foveated rendering.</figcaption></figure><h3>Conclusion</h3><p>In conclusion, the contributions of foveated rendering to VR devices and user experience are undeniable. This type of optimizations and quality increase not only makes this experience accessible and responsive, but also offers great development in the fields of enterprise, training, medical and education. Thanks to these developments, we can come up with innovative solutions and sign a better future.</p><h3><strong>Citations</strong></h3><p>“What is foveated rendering?”, Tobii, <a href="https://www.tobii.com/blog/what-is-foveated-rendering">https://www.tobii.com/blog/what-is-foveated-rendering</a>, Accessed 1 Nov. 2024</p><p>“Foveated rendering on StarVR One”, ZeroLight, <a href="https://zerolight.com/news/foveated-rendering-on-starvr-one-2">https://zerolight.com/news/foveated-rendering-on-starvr-one-2</a>, Accessed 1 Nov. 2024</p><p>“Foveated Rendering”, Tobii, <a href="https://developer.tobii.com/xr/learn/foveation/rendering/">https://developer.tobii.com/xr/learn/foveation/rendering/</a>, Accessed 2 Nov. 2024</p><h3>About Me</h3><blockquote>My name is Huseyn, and I’m a 16-year-old entrepreneur and game developer who is really passionate about innovation and creating new and complex stuff. Since I was twelve years old, I have been interested in programming and have created a number of startups and projects. I currently work as the community manager at GamePons, as a young member at The New York Academy of Sciences, and as a member of TKS’s Cohort ’24. Aside from that, I enjoy working on low-level projects like graphics programming and assisting others to advance in their careers. You can get more information about me via <a href="https://coderloff.me/">my personal website</a>.</blockquote><blockquote>Feel free to contact me if you have any questions about my article or if you would like to connect via <a href="https://linkedin.com/in/coderloff">LinkedIn</a> or <a href="/service/mailto:coderloff@gmail.com">E-mail</a>.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e87d62d5cd25" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Tic-Tac-Toe Game in Zig: A Fun Coding Project]]></title>
            <link>https://huseynismayilov.medium.com/tic-tac-toe-game-in-zig-46d7350947fd?source=rss-fad42706d941------2</link>
            <guid isPermaLink="false">https://medium.com/p/46d7350947fd</guid>
            <category><![CDATA[tic-tac-toe]]></category>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[zig]]></category>
            <dc:creator><![CDATA[Huseyn Ismayilov]]></dc:creator>
            <pubDate>Sun, 10 Sep 2023 11:35:38 GMT</pubDate>
            <atom:updated>2023-09-10T11:35:38.677Z</atom:updated>
            <content:encoded><![CDATA[<p>Tic-Tac-Toe, also known as “X and O,” is a classic game that has been enjoyed by people of all ages for generations. It’s a simple yet engaging game that can be a great coding project for beginners to hone their programming skills. In this article, we will explore how to create a Tic-Tac-Toe game using the Zig programming language.</p><h3>Introduction</h3><p>Before we dive into the code, let’s take a moment to understand what Tic-Tac-Toe is and what our objectives are in building this game.</p><p>Tic-Tac-Toe is a two-player game played on a 3x3 grid. The goal of the game is to be the first to get three of your symbols (either “X” or “O”) in a row, column, or diagonal. If the entire board is filled, and no player has achieved this, the game is declared a draw.</p><h3>Setting Up Zig</h3><p>To get started, you’ll need to have Zig installed on your computer. You can download it from the official Zig website: <a href="https://ziglang.org/">ziglang.org</a>.</p><h3>The Zig Code</h3><p>Now, let’s take a closer look at the Zig code that powers our Tic-Tac-Toe game. I won’t cover every detail of the code here, but I’ll provide an overview of its key components.</p><pre>const std = @import(&quot;std&quot;);<br>const print = std.debug.print;<br><br>const Movement = struct { move: u8, place: u8 };<br><br>fn get_move(move: u8, table:[3][3]u8) !Movement {<br>    const stdin = std.io.getStdIn().reader();<br><br>    var movement: Movement = undefined;<br><br><br>    print(&quot;Player {c} -&gt; Enter place: &quot;, .{move});<br><br>    var buffer: [1024]u8 = undefined;<br><br>    var place:u8 = undefined;<br><br>    if(try stdin.readUntilDelimiterOrEof(buffer[0..], &#39;\n&#39;)) |input| {<br>        while(input[0] &lt; 48 or input[0] &gt; 57){<br>            return try get_move(move, table);<br>        }<br>        place = input[0]-48;<br>    }else {<br>        return try get_move(move, table);<br>    }<br><br>    movement.move = move;<br>    movement.place = place;<br><br>    // Error handling<br>    while(movement.place &lt; 1 or movement.place &gt; 9){<br>        return try get_move(move, table);<br>    }<br>    var index = movement.place-1;<br>    while(table[index / 3][index % 3] == &#39;X&#39; or table[index / 3][index % 3] == &#39;O&#39;){<br>        return try get_move(move, table);<br>    }<br><br>    return Movement{ .move = move, .place = place };<br>}<br><br>fn check_win(table: [3][3]u8) !u8 {<br>    if ((table[0][0] == &#39;X&#39; and table[0][1] == &#39;X&#39; and table[0][2] == &#39;X&#39;) or // Horizontal: 1<br>        (table[1][0] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[1][2] == &#39;X&#39;) or // Horizontal: 2<br>        (table[2][0] == &#39;X&#39; and table[2][1] == &#39;X&#39; and table[2][1] == &#39;X&#39;) or // Horizontal: 3<br>        (table[0][0] == &#39;X&#39; and table[1][0] == &#39;X&#39; and table[2][0] == &#39;X&#39;) or // Vertical: 1<br>        (table[0][1] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][1] == &#39;X&#39;) or // Vertical: 2<br>        (table[0][2] == &#39;X&#39; and table[1][2] == &#39;X&#39; and table[2][2] == &#39;X&#39;) or // Vertical: 3<br>        (table[0][0] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][2] == &#39;X&#39;) or // Diagonal: ↘<br>        (table[0][2] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][0] == &#39;X&#39;))   // Diagonal: ↙<br>    { <br>        return &#39;X&#39;;<br>    }<br>    else if ((table[0][0] == &#39;O&#39; and table[0][1] == &#39;O&#39; and table[0][2] == &#39;O&#39;) or // Horizontal: 1<br>        (table[1][0] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[1][2] == &#39;O&#39;) or // Horizontal: 2<br>        (table[2][0] == &#39;O&#39; and table[2][1] == &#39;O&#39; and table[2][1] == &#39;O&#39;) or // Horizontal: 3<br>        (table[0][0] == &#39;O&#39; and table[1][0] == &#39;O&#39; and table[2][0] == &#39;O&#39;) or // Vertical: 1<br>        (table[0][1] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][1] == &#39;O&#39;) or // Vertical: 2<br>        (table[0][2] == &#39;O&#39; and table[1][2] == &#39;O&#39; and table[2][2] == &#39;O&#39;) or // Vertical: 3<br>        (table[0][0] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][2] == &#39;O&#39;) or // Diagonal: ↘<br>        (table[0][2] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][0] == &#39;O&#39;))   // Diagonal: ↙<br>    { <br>        return &#39;O&#39;;<br>    }<br>    else if (<br>        table[0][0] != &#39; &#39; and table[0][1] != &#39; &#39; and table[0][2] != &#39; &#39; and<br>        table[1][0] != &#39; &#39; and table[1][1] != &#39; &#39; and table[1][2] != &#39; &#39; and<br>        table[2][0] != &#39; &#39; and table[2][1] != &#39; &#39; and table[2][2] != &#39; &#39;<br>    ) {<br>        return 1;<br>    }<br>    else {<br>        return 0;<br>    }<br>}<br><br>fn print_table(table: [3][3]u8) !void {<br>    print(&quot;\n&quot;, .{});<br>    for (table, 0..) |row, i| {<br>        for (row, 0..) |item, j| {<br>            print(&quot; {c} &quot;, .{item});<br>            if (j != 2) {<br>                print(&quot;|&quot;, .{});<br>            }<br>        }<br>        if (i != 2) {<br>            print(&quot;\n------------\n&quot;, .{});<br>        } else {<br>            print(&quot;\n&quot;, .{});<br>        }<br>    }<br>    print(&quot;\n&quot;, .{});<br>}<br><br>fn print_welcome() !void{<br>    print(&quot;---------------------------\n&quot;, .{});<br>    print(&quot;Welcome to Tic-Tac-Toe Game\n&quot;, .{});<br>    print(&quot;---------------------------\n&quot;, .{});<br>}<br><br>fn print_bye(winState: u8) !void{<br>    print(&quot;------------------\n&quot;, .{});<br>    print(&quot;Game Ended! &quot;, .{});<br>    if(winState == &#39;X&#39;) std.debug.print(&quot;X won!\n&quot;, .{})<br>    else if(winState == &#39;O&#39;) std.debug.print(&quot;O won!\n&quot;, .{})<br>    else std.debug.print(&quot;Draw!\n&quot;, .{});<br>    print(&quot;------------------\n&quot;, .{});<br><br>    print(&quot;\nPress &#39;Enter&#39; to exit... &quot;, .{});<br>    var buffer: [1024]u8 = undefined;<br>    const temp = (try std.io.getStdIn().reader().readUntilDelimiterOrEof(buffer[0..], &#39;\n&#39;)).?;<br>    _ = temp;<br>}<br><br>pub fn main() !void {<br>    var table = [3][3]u8{ [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; }, [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; }, [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; } };<br>    var move: u8 = &#39;X&#39;;<br><br>    try print_welcome();<br><br>    var winState = try check_win(table);<br><br>    while (winState == 0) {<br>        try print_table(table);<br><br>        var movement = try get_move(move, table);<br><br>        const index = movement.place - 1;<br>        table[index / 3][index % 3] = move;<br><br>        move = if(move == &#39;X&#39;) &#39;O&#39; else &#39;X&#39;;<br><br>        winState = try check_win(table);<br>    }<br><br>    try print_table(table);<br><br>    try print_bye(winState);<br>}</pre><h3>The get_move Function</h3><p>The get_move function is responsible for taking player input and validating it. It ensures that the entered move is within the valid range and that the selected cell is not already occupied.</p><pre>fn get_move(move: u8, table:[3][3]u8) !Movement {<br>    const stdin = std.io.getStdIn().reader();<br><br>    var movement: Movement = undefined;<br><br><br>    print(&quot;Player {c} -&gt; Enter place: &quot;, .{move});<br><br>    var buffer: [1024]u8 = undefined;<br><br>    var place:u8 = undefined;<br><br>    if(try stdin.readUntilDelimiterOrEof(buffer[0..], &#39;\n&#39;)) |input| {<br>        while(input[0] &lt; 48 or input[0] &gt; 57){<br>            return try get_move(move, table);<br>        }<br>        place = input[0]-48;<br>    }else {<br>        return try get_move(move, table);<br>    }<br><br>    movement.move = move;<br>    movement.place = place;<br><br>    // Error handling<br>    while(movement.place &lt; 1 or movement.place &gt; 9){<br>        return try get_move(move, table);<br>    }<br>    var index = movement.place-1;<br>    while(table[index / 3][index % 3] == &#39;X&#39; or table[index / 3][index % 3] == &#39;O&#39;){<br>        return try get_move(move, table);<br>    }<br><br>    return Movement{ .move = move, .place = place };<br>}</pre><h3>Checking for a Win</h3><p>The check_win function checks the game board to determine if a player has won or if the game has ended in a draw.</p><pre>fn check_win(table: [3][3]u8) !u8 {<br>    if ((table[0][0] == &#39;X&#39; and table[0][1] == &#39;X&#39; and table[0][2] == &#39;X&#39;) or // Horizontal: 1<br>        (table[1][0] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[1][2] == &#39;X&#39;) or // Horizontal: 2<br>        (table[2][0] == &#39;X&#39; and table[2][1] == &#39;X&#39; and table[2][1] == &#39;X&#39;) or // Horizontal: 3<br>        (table[0][0] == &#39;X&#39; and table[1][0] == &#39;X&#39; and table[2][0] == &#39;X&#39;) or // Vertical: 1<br>        (table[0][1] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][1] == &#39;X&#39;) or // Vertical: 2<br>        (table[0][2] == &#39;X&#39; and table[1][2] == &#39;X&#39; and table[2][2] == &#39;X&#39;) or // Vertical: 3<br>        (table[0][0] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][2] == &#39;X&#39;) or // Diagonal: ↘<br>        (table[0][2] == &#39;X&#39; and table[1][1] == &#39;X&#39; and table[2][0] == &#39;X&#39;))   // Diagonal: ↙<br>    { <br>        return &#39;X&#39;;<br>    }<br>    else if ((table[0][0] == &#39;O&#39; and table[0][1] == &#39;O&#39; and table[0][2] == &#39;O&#39;) or // Horizontal: 1<br>        (table[1][0] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[1][2] == &#39;O&#39;) or // Horizontal: 2<br>        (table[2][0] == &#39;O&#39; and table[2][1] == &#39;O&#39; and table[2][1] == &#39;O&#39;) or // Horizontal: 3<br>        (table[0][0] == &#39;O&#39; and table[1][0] == &#39;O&#39; and table[2][0] == &#39;O&#39;) or // Vertical: 1<br>        (table[0][1] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][1] == &#39;O&#39;) or // Vertical: 2<br>        (table[0][2] == &#39;O&#39; and table[1][2] == &#39;O&#39; and table[2][2] == &#39;O&#39;) or // Vertical: 3<br>        (table[0][0] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][2] == &#39;O&#39;) or // Diagonal: ↘<br>        (table[0][2] == &#39;O&#39; and table[1][1] == &#39;O&#39; and table[2][0] == &#39;O&#39;))   // Diagonal: ↙<br>    { <br>        return &#39;O&#39;;<br>    }<br>    else if (<br>        table[0][0] != &#39; &#39; and table[0][1] != &#39; &#39; and table[0][2] != &#39; &#39; and<br>        table[1][0] != &#39; &#39; and table[1][1] != &#39; &#39; and table[1][2] != &#39; &#39; and<br>        table[2][0] != &#39; &#39; and table[2][1] != &#39; &#39; and table[2][2] != &#39; &#39;<br>    ) {<br>        return 1;<br>    }<br>    else {<br>        return 0;<br>    }<br>}</pre><h3>Displaying the Game Board</h3><p>The print_table function displays the current state of the game board. It&#39;s crucial for players to see the board and make their moves.</p><pre>fn print_table(table: [3][3]u8) !void {<br>    print(&quot;\n&quot;, .{});<br>    for (table, 0..) |row, i| {<br>        for (row, 0..) |item, j| {<br>            print(&quot; {c} &quot;, .{item});<br>            if (j != 2) {<br>                print(&quot;|&quot;, .{});<br>            }<br>        }<br>        if (i != 2) {<br>            print(&quot;\n------------\n&quot;, .{});<br>        } else {<br>            print(&quot;\n&quot;, .{});<br>        }<br>    }<br>    print(&quot;\n&quot;, .{});<br>}</pre><h3>Running the Game</h3><p>In the main function, the game loop is implemented. It continually takes player input, updates the board, and checks for a win or draw until the game is over.</p><pre>pub fn main() !void {<br>    var table = [3][3]u8{ [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; }, [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; }, [3]u8{ &#39; &#39;, &#39; &#39;, &#39; &#39; } };<br>    var move: u8 = &#39;X&#39;;<br><br>    try print_welcome();<br><br>    var winState = try check_win(table);<br><br>    while (winState == 0) {<br>        try print_table(table);<br><br>        var movement = try get_move(move, table);<br><br>        const index = movement.place - 1;<br>        table[index / 3][index % 3] = move;<br><br>        move = if(move == &#39;X&#39;) &#39;O&#39; else &#39;X&#39;;<br><br>        winState = try check_win(table);<br>    }<br><br>    try print_table(table);<br><br>    try print_bye(winState);<br>}</pre><h3>Conclusion</h3><p>Congratulations! You’ve just created a simple yet functional Tic-Tac-Toe game in Zig. This project not only allowed you to flex your programming muscles but also provided valuable experience in handling user input, implementing game logic, and creating a fun interactive application.</p><p>Feel free to expand on this project by adding more features, such as a graphical user interface (GUI) or implementing an unbeatable AI opponent.</p><p>Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=46d7350947fd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Dunger: Dungeon Generation Tool for Unity]]></title>
            <link>https://huseynismayilov.medium.com/introducing-dunger-2d6c11fbe17b?source=rss-fad42706d941------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d6c11fbe17b</guid>
            <category><![CDATA[unity]]></category>
            <category><![CDATA[dungeon]]></category>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[game-development]]></category>
            <dc:creator><![CDATA[Huseyn Ismayilov]]></dc:creator>
            <pubDate>Sun, 10 Sep 2023 11:21:19 GMT</pubDate>
            <atom:updated>2023-09-10T11:21:19.809Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VDznNeIssvzj97Qe0vBpTA.png" /></figure><p>Dunger is an open-source project I’ve been working on, designed to streamline the process of creating procedurally generated dungeons in Unity. Whether you’re developing a game, simulation, or any Unity project that requires dynamic-level design, Dunger is your go-to solution.</p><h4>Key Features of Dunger:</h4><ul><li>Procedural Dungeon Generation: Dunger streamlines the process of generating dungeons with just a few clicks. It uses procedural algorithms to create unique layouts, ensuring that players never experience the same dungeon twice.</li><li>Unity Integration: Built exclusively for Unity, Dunger seamlessly integrates into your Unity projects. You can easily incorporate it into your game development workflow and start generating dungeons in no time.</li><li>Configurable Parameters: Customize the dungeons to fit your specific needs. Adjust parameters like dungeon size, complexity, and room distribution to achieve the desired level of challenge and variety.</li><li>User-Friendly Interface: Dunger provides an intuitive interface that makes it accessible to both seasoned developers and newcomers. You don’t need to be a coding expert to create captivating dungeons.</li><li>Documentation and Support: Dunger comes with comprehensive documentation and support resources to help you get started and troubleshoot any issues you might encounter.</li></ul><h4>Why Choose Dunger:</h4><p>Dunger simplifies the process of adding randomized dungeons to your Unity games or applications. Whether you’re developing a roguelike adventure, a dungeon crawler, or any game that benefits from procedural level design, Dunger can save you time and effort while enhancing the player experience.</p><p>With Dunger, you can harness the power of procedural generation in Unity to keep your players engaged with fresh and unpredictable dungeons, making your project stand out in the world of game development.</p><p>Get started with Dunger in Unity today and bring dynamic dungeon exploration to your game world!</p><h4>Built With</h4><p>Dunger is powered by the Unity game engine, harnessing its versatile capabilities for seamless integration and exceptional performance. The project leverages Unity’s robust tools and resources to provide a user-friendly environment for generating random dungeons. With Dunger, you can take advantage of Unity’s powerful features to create dynamic and engaging game worlds filled with procedurally generated dungeons.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/179/0*e9AcWTzD3syHNOqF" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/148/0*DgjURYfu-y5ZpEYp" /></figure><h3>Getting Started</h3><p>This is an example of how you may give instructions on setting up your project locally. To get a local copy up and running follow these simple example steps.</p><h4>Prerequisites</h4><p>Before installing Dunger, ensure that you have the following prerequisites in place:</p><ul><li>Unity: Dunger is specifically designed for the Unity game engine. Make sure you have Unity installed on your development machine. You can download Unity from the official Unity website.</li><li>GitHub Access: If you plan to clone Dunger from GitHub, you’ll need a GitHub account and a Git client installed on your machine for version control.</li><li>Existing Unity Project: If you’re integrating Dunger into an existing Unity project, ensure that your project is set up and compatible with the Unity version specified in Dunger’s documentation.</li></ul><p>Having these prerequisites in order will help you smoothly install and work with Dunger in your Unity environment.</p><h4>Installation</h4><p>Dunger offers a hassle-free installation process, providing two convenient options:</p><h4>Cloning from GitHub:</h4><p>To start a new project with Dunger, simply clone the Dunger repository from GitHub to your local machine. You can then open the project directly in Unity, making it easy to get started with dungeon generation right away.</p><ol><li>Clone the repo</li></ol><pre>git clone https://github.com/coderloff/dunger</pre><p>2. Open the cloned project using Unity Hub</p><h4>Importing as a Unity Package:</h4><p>If you already have an existing Unity project and want to integrate Dunger, you can import it as a Unity package. This allows you to seamlessly add Dunger’s dungeon generation capabilities to your ongoing project, enhancing its gameplay with dynamic dungeons.</p><ol><li>Download unitypackage by clicking <a href="https://github.com/coderloff/dunger/releases/download/v1.0.0/Dunger.unitypackage">here</a></li><li>Open your Unity project</li><li>Double-click on the downloaded package</li><li>Click install in Unity</li></ol><h4>Usage</h4><p>Using Dunger to generate random dungeons in your Unity project is a straightforward process. Here’s a quick guide:</p><ol><li><strong>New Project Setup:</strong> If you’re starting a new project, clone Dunger from GitHub and open it in Unity. Dunger will be ready to use, and you can begin customizing and generating dungeons right away.</li><li><strong>Existing Project Integration:</strong> If you have an existing Unity project, import Dunger as a Unity package. Once integrated, you can access Dunger’s functionality through Unity’s user-friendly interface.</li><li><strong>Customization:</strong> Customize your dungeons by adjusting parameters such as size, complexity, and room distribution to achieve the desired level of challenge and variety.</li><li><strong>Script Integration:</strong> For advanced users, Dunger offers script-based integration, allowing you to control dungeon generation programmatically. Use this option to create unique and dynamic gameplay experiences.</li></ol><h3>Contributing</h3><p>We welcome contributions from the community to help Dunger thrive. Here’s how you can get involved:</p><ol><li><strong>Filing Issues:</strong> If you encounter bugs or have suggestions for improvements, please open an issue on our GitHub repository. Be sure to provide details and context to help us understand the issue.</li><li><strong>Pull Requests:</strong> We appreciate pull requests for bug fixes, feature enhancements, or new additions. Make sure your contributions align with our project’s goals and coding standards.</li><li><strong>Documentation:</strong> Improving our documentation is a valuable way to contribute. If you find areas that need clarification or want to add examples, your help is greatly appreciated.</li><li><strong>Community Support:</strong> Join discussions, answer questions, and share your knowledge on our community forums. Your expertise can be a valuable resource for fellow Dunger users.</li><li><strong>Spread the Word:</strong> Help us grow the Dunger community by sharing your experiences with others. Tweet about your projects, write blog posts or create tutorials featuring Dunger.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d6c11fbe17b" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>