Play tic-tac-toe and never lose (There exists some challenges that require to use the best strategy, but here we don't. Even if you are able to win, you are allowed to make a tie)

Challenge

Write a program which plays the game tic-tac-toe. It must not lose (therefore, it should end the game either with a tie or by winning).

Allowed I/O methods


Input may be the current board. You can assume that all previous moves of the 2nd player were played by your engine.
Input may be the first player's moves, and your function stores which moves happened in the past. In this case the function is called multiple times, once for each move; or the function/program prompt input for multiple times.
You are allowed to take an extra input saying if you are the first player, or write two (possibly related) functions to solve the first-player problem and the second-player one. If your program need use the input method 2 (multiple call), you can decide what is passed in the first call.
Output may be the board after your turn.
Output may be your move.
A move may be represented as a pair of numbers (can be 0-indexing or 1-indexing), a number in range 0~8, or a number in range 1~9.
The board may be represented as a 3×3 array, or an array of length 9. Even if the language have 0-indexing array, you can use 1-indexing.
The cells on the grid may use any 3 different values to indicate X, O and empty.


Winning criteria

Shortest code in each language win.
Befunge, 181 168 bytes
&gt;&gt;4&amp;5pp20555&gt;&gt;03&gt;16p\::5g8%6p5v
 ^p5.:g605$_ #!&lt;^_|#:-1g61+%8g&lt;
543217539511|:_^#-&gt;#g0&lt;&gt;8+00p3+5%09638527419876
v&lt;304p$_v#:-&gt;#$$:2`#3_:^
&gt;#\3#13#&lt;111v124236478689189378

Positions on the board are numbered 1 to 9. By default you get the first move, but if you want to allow the computer to go first, you can just enter 0 for your first move. When you've made a move, the computer will respond with a number indicating their move.
There are no checks to make sure you don't enter a valid move, and there also no checks to see if anyone has won or lost. Once their are no more moves to be made, the program just goes into an infinite loop.
It's a bit difficult to test this online, since there are no online interpreters with interactive input. However, if you know what moves you're going to make in advance (which assumes you know how the computer is going to respond), you can kind of test on TIO with those moves preprogrammed.
User plays first: Try it online!
Computer plays first: Try it online!
To makes it easier to see what's going on, I've also got a version that outputs the board between moves.
User plays first: Try it online!
Computer plays first: Try it online!
Note that you'll have to wait for TIO to timeout before you can see the results.
Explanation
The board is stored in the Befunge memory area as a flat array of 9 values, indexed from 1 to 9. This lets us use the zero offset as a special case &quot;no move&quot; when we want to let the computer play first. Player moves are stored as 4, and computer moves as 5. To start with all positions are initialised to 32 (the Befunge memory default), so whenever we access the board we mod with 8, so we'll get back either 0, 4 or 5.
Given that arrangement, if we sum the values of any three positions on the board, we know that the computer is one move away from winning if the total is 10, the player is one move away from winning if the total is 8, and the positions are shared between computer and player (but still one position is free) if the total is 9.
Our entire strategy is based around this concept. We have a routine that takes a list of triples indicating sets of three positions on the board, we calculate the sum of those positions, and if the sum equals a certain total, the computer moves to whichever of the positions in the set is free.
The main list of triples that we test are the winning combinations (1/2/3, 1/5/9, 1/4/7, etc.). We first look for a total of 10 (the computer is about to win), and then a total of 8 (the player is about to win and we need to block that move). Less obviously, we also check for a total of 9 (if the player and computer each have one of the positions, it's a good strategy for the computer to take the third).
Prior to that last scenario, the other strategic move we make is to check all the corner sets (1/2/4, 2/3/6, etc.) as well as two opposing corner combinations (1/8/9 and 3/7/8). If any of these combinations sum to 8, i.e. the player has taken two of the positions, it's a good strategy for the computer to take the remaining free position.
Finally, there are a two special case moves. First, we always try and take the center position before any other move. This is achieved with the same routine as all our other moves, just passing in a single triple, 5/5/5, and a target sum of 0. Additionally, if all other test have failed to find a move, we try to take one of the top corners as a last resort. Again this is simply achieved by testing the triples 1/1/1 and 3/3/3, with a target sum of 0.
I don't think this is necessarily a perfect strategy - there may be games that the computer draws which could potentially have been won - but it's good enough to never lose a match. I've run a test script that tried to play every possible move against the computer, and for every valid sequence of moves, the computer either won or drew the game.